【问题标题】:Why the decrypted hash does not match the encrypted hash in the signature?为什么解密的哈希与签名中的加密哈希不匹配?
【发布时间】: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


【解决方案1】:

好的,我设法找出原因.. 显然 decryptedHash 并不是真正的实际哈希值。我需要去https://lapo.it/asn1js/ 转换它。我在那个领域不是很精通,但我通过查看这篇帖子找到了一些线索https://crypto.stackexchange.com/questions/80768/openssl-extract-hash-algorithm-from-signature-data-pkcs1-v-1-5

decryptedHash 似乎是 DER ANS1 格式。

在我的程序中再添加 3 行,我可以匹配 manualHash

const valueGotFromLapoSite = '11D4DDC357E0822968DBFD226B6E1C2AAC018D076A54DA4F65E1DC8180684AC3';
const myHash = Buffer.from(valueGotFromLapoSite, 'hex').toString('base64');
console.log(`myHash: ${myHash}`);

输出:

true
decryptedHash: MDEwDQYJYIZIAWUDBAIBBQAEIBHU3cNX4IIpaNv9ImtuHCqsAY0HalTaT2Xh3IGAaErD
manualHash: EdTdw1fggilo2/0ia24cKqwBjQdqVNpPZeHcgYBoSsM=
myHash: EdTdw1fggilo2/0ia24cKqwBjQdqVNpPZeHcgYBoSsM=

【讨论】:

    猜你喜欢
    • 2017-04-25
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    相关资源
    最近更新 更多