【发布时间】:2021-04-25 03:07:57
【问题描述】:
据我了解,签名中由私钥加密的哈希应该与有效负载的哈希匹配。我编写了一个小节点程序来测试这个概念,但即使验证通过,哈希也无法匹配。
以下是我尝试过的。
import crypto from 'crypto';
// generate some stub keys for the test program
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
publicKeyEncoding: {
type: 'spki',
format: 'pem',
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem',
},
});
// the payload to be signed
const payload = 'helloWorld';
// create the signature
const signatureFunction = crypto.createSign('SHA256');
signatureFunction.write(payload);
signatureFunction.end();
const signature = signatureFunction.sign(privateKey, 'base64');
// verify the signature
const verifyFunction = crypto.createVerify('SHA256');
verifyFunction.write(payload);
verifyFunction.end();
// the result is "true" which means my public key can verify the encrypted hash
console.log(verifyFunction.verify(publicKey, signature, 'base64'));
// decrypt and check what is the hash
const decryptedHash = crypto.publicDecrypt(publicKey, Buffer.from(signature, 'base64'));
console.log(`decryptedHash: ${decryptedHash.toString('base64')}`);
// manually generate the hash
const manualHash = crypto
.createHash('SHA256')
.update(payload)
.digest('base64');
console.log(`manualHash: ${manualHash}`);
下面是输出:
true
decryptedHash: MDEwDQYJYIZIAWUDBAIBBQAEIBHU3cNX4IIpaNv9ImtuHCqsAY0HalTaT2Xh3IGAaErD
manualHash: EdTdw1fggilo2/0ia24cKqwBjQdqVNpPZeHcgYBoSsM=
我的问题是为什么 decryptedHash 与 manualHash 不匹配?
【问题讨论】:
-
RSA 签名不是在完整的有效负载上完成,而是在有效负载的 (SHA-256) 哈希上完成,因为性能原因(RSA 在大数据上会变得非常低)。签名本身是一些计算的结果,与哈希无关,它只是一个值。因此,手动计算哈希将得到与(“解密”)签名不同的结果。顺便说一句:RSA 私钥-公钥环境中的解密将使用私钥完成。所以结论是:签名不是哈希。
-
嗨@MichaelFehr。是的,我知道签名不是哈希。但我认为如果你解密签名,内容应该是有效载荷的哈希值。我还在学习我的方法,如果我错了,请纠正我。我还在下面发布了更新,我现在设法匹配有效负载的哈希
标签: javascript node.js sha256 cryptojs