Python 中的数字签名签名和 Nodejs 中的验证

问题描述 投票:0回答:0

我正在使用 Python Cryptography 和 Nodejs Crypto 库。我希望在 Python 中对签名进行数字签名并在 Nodejs 中进行验证。

示例密钥对:从 Hashicorp Vault 获得(类型:ecdsa-p521)

PRIVATE_KEY="-----BEGIN EC PRIVATE KEY-----\nMIHcAgEBBEIB1ZsDtu9EeMUma3p0M4jWrA4jJrBirDyhLfATvXVMWNDmrH5EX49T\ndOzAsKq92IXi2g1HtdIaYBBTde5lkBNfUK+gBwYFK4EEACOhgYkDgYYABAESgmpD\nCcElrFK/HPwJaNUkSly25hcQe0KnSFoIIlIBVba5jPxz2erUDIPr34RINUb3LS7j\n5MxELHl/VINKFdNhzgGJT4IWzL9VR6p8auN4+DNy7lLr4veBvB3yY87MkfaRWqlB\nyjpMre0vudtOAHUbZ6F6l4BPBPIAQaYHHiuNWSrjlg==\n-----END EC PRIVATE KEY-----"

PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBEoJqQwnBJaxSvxz8CWjVJEpctuYXEHtCp0haCCJSAVW2uYz8c9nq1AyD69+ESDVG9y0u4+TMRCx5f1SDShXTYc4BiU+CFsy/VUeqfGrjePgzcu5S6+L3gbwd8mPOzJH2kVqpQco6TK3tL7nbTgB1G2ehepeATwTyAEGmBx4rjVkq45Y=\n-----END PUBLIC KEY-----"

蟒蛇

import base64
from os import urandom
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec, utils
from cryptography.hazmat.primitives.serialization import (
    load_pem_private_key,
    load_pem_public_key,
)
from cryptography.hazmat.backends import default_backend
from cryptography.exceptions import InvalidSignature


def sign() -> "dict[str, str]":
    # ecdsa signing
    privKey = load_pem_private_key(
        PRIVATE_KEY.encode(),
        password=None,
        backend=default_backend,
    )
    msg = urandom(12)

    chosen_hash = hashes.SHA256()
    hasher = hashes.Hash(chosen_hash, backend=default_backend)
    hasher.update(msg)
    digest = hasher.finalize()

    signature = privKey.sign(
        digest,
        ec.ECDSA(utils.Prehashed(chosen_hash)),
    )

    return {
        "msg": base64.b64encode(msg).decode(),
        "sign": base64.b64encode(signature).decode(),
    }


def verify(signObj: "dict[str, str]") -> bool:
    pubKey = load_pem_public_key(
        PUBLIC_KEY.encode(),
        backend=default_backend,
    )
    try:
        pubKey.verify(
            base64.b64decode(signObj["sign"].encode()),
            base64.b64decode(signObj["msg"].encode()),
            ec.ECDSA(hashes.SHA256()),
        )
    except InvalidSignature:
        return False

    return True


if __name__ == "__main__":
    res = sign()
    print(res)
    print(verify(res))

就其本身而言,签名和验证工作。

打字稿:

import * as crypto from "crypto";

const algo = "sha256";
const base64 = "base64";

class SignObj {
  readonly msg: string;
  readonly sign: string;

  constructor(msg: string, sign: string) {
    this.msg = msg;
    this.sign = sign;
  }
}

function sign(): SignObj {
  const msg = crypto.randomBytes(12);

  const hash = crypto.createHash(algo).update(msg).end();
  const hashDigest = hash.digest();

  const signer = crypto.createSign(algo);
  signer.write(hashDigest);
  signer.end();

  const sign = signer.sign(PRIVATE_KEY, base64);

  return new SignObj(msg.toString(base64), sign);
}

function verify(signObj: SignObj): boolean {
  const hash = crypto
    .createHash(algo)
    .update(Buffer.from(signObj.msg, base64))
    .end();
  const hashDigest = hash.digest();

  const verifier = crypto.createVerify(algo);
  verifier.write(hashDigest);
  verifier.end();

  return verifier.verify(PUBLIC_KEY, Buffer.from(signObj.sign, base64));
}

console.log(verify(sign()));

再次,签名和验证本身就有效。

但是如果我们手动提取值,例如,从 Python 到 Typescript 的结果

{
    'msg': 'Oz4ZRvzcTRs7CEKV', 
    'sign': 'MIGGAkEkbIqN8uPwzMf50NiqXKuSdT4c+8Lchz7o5eKPfiPp3jMDtW1TqQseCJw7/8mIcvTRdYeFlYsf58vFbxkk/jpi/QJBBkw9MKelCXcEPecM5/5HqJrkD2XijtNgj7AKzsMTv/Y7721S6hnb48sBKj6DTQ9Dfnsf1uPZNb4KIa7KhwX5ebw='
}

放入打字稿

const res = new SignObj(
  "Oz4ZRvzcTRs7CEKV",
  "MIGGAkEkbIqN8uPwzMf50NiqXKuSdT4c+8Lchz7o5eKPfiPp3jMDtW1TqQseCJw7/8mIcvTRdYeFlYsf58vFbxkk/jpi/QJBBkw9MKelCXcEPecM5/5HqJrkD2XijtNgj7AKzsMTv/Y7721S6hnb48sBKj6DTQ9Dfnsf1uPZNb4KIa7KhwX5ebw="
);
console.log(res);
console.log(verify(res)); // --> False

不太确定出了什么问题。任何帮助都会有所帮助。提前谢谢~

python-3.x typescript digital-signature ecdsa
© www.soinside.com 2019 - 2024. All rights reserved.