为什么解密的哈希与签名中的加密哈希不匹配?

Why the decrypted hash does not match the encrypted hash in the signature?

根据我的理解,签名中由私钥加密的哈希值应该与有效负载的哈希值相匹配。我写了一个小节点程序来测试这个概念,但是即使验证通过了哈希也无法匹配。

下面是我试过的。

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=

我的问题是为什么 decryptedHashmanualHash 不匹配?

好的,我设法找出原因.. 显然 decryptedHash 并不是真正的实际哈希值。我需要去 https://lapo.it/asn1js/ to convert it. I am not very well-verse in that area but I manage to find some clue by looking at this post 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=