RSA-SHA256 签名算法未按预期运行

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

我最近采用了一些第三方安全软件,我试图了解如何处理我们从他们那里收到的签名消息。在此过程中,我使用 Node Crypto 库来巩固我对概念的理解。

据我了解RSA-SHA256签名算法,在签名过程中:

  • 消息使用 SHA256 进行哈希处理;
  • 使用私钥对哈希值进行加密,生成签名。

然后客户端将原始消息、公钥和签名发送给我们。验证签名的过程如下:

  • 公钥用于解密签名;
  • 我们使用 SHA256 对原始消息进行哈希处理,并验证哈希值是否与解密的签名匹配。

如果是这种情况,那么在下面的代码片段中:

const { 
  generateKeyPairSync,
  publicDecrypt, privateEncrypt,
  createSign, createVerify,
  createHash,
} = require('crypto');

const { privateKey, publicKey } = generateKeyPairSync('rsa', {
  modulusLength: 2048,
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem',
  },
  privateKeyEncoding: {
    type: 'pkcs8',
    format: 'pem',
  },
});
const messageToSign = "Yma o hyd";

const signer = createSign('RSA-SHA256');
signer.update(messageToSign);
const signature = signer.sign(privateKey);
console.log('Signed message', signature.toString('hex'));

const verifier = createVerify('RSA-SHA256');
verifier.update(messageToSign);
const isVerified = verifier.verify(publicKey, signature);
console.log('isVerified:', isVerified);

const hash = createHash('SHA256').update(messageToSign).digest();
console.log('hash in hex', hash.toString('hex'));
const hashEncryptedWithPrivateKey = privateEncrypt(
  privateKey,
  hash,
);

console.log('encrypted hash', hashEncryptedWithPrivateKey.toString('hex'));
const signatureDecryptedWithPublicKey = publicDecrypt(
  publicKey,
  signature
);
console.log('Signature decrypted with public key', signatureDecryptedWithPublicKey.toString('hex'));

我希望

signatureDecryptedWithPublicKey.toString('hex')
能够匹配
hash.toString('hex')
,但事实并非如此。

签名者所做的不仅仅是 RSA 和 SHA256 的简单组合吗?

node.js node-crypto
1个回答
0
投票

您的考虑中没有考虑填充。

为了使

hashEncryptedWithPrivateKey
等于
signature
,不是必须将
hash
传递给
privateEncrypt()
,而是将
DigestInfo
T
的DER编码,这适用于SHA256:
0x3031300d060960864801650304020105000420 || hash
,因此:

const hashEncryptedWithPrivateKey = privateEncrypt(
  privateKey,
  Buffer.concat([Buffer.from('3031300d060960864801650304020105000420', 'hex'), hash])
);

同样,

const signatureDecryptedWithPublicKey = publicDecrypt(
  publicKey,
  signature
);

不返回

hash
而是
T

© www.soinside.com 2019 - 2024. All rights reserved.