为什么 Node.js' 符号和 CryptographicEngine 符号结果之间存在差异?

Why is there a difference between Node.js' sign and CryptographicEngine sign results?

我正在尝试使用 UWP 的 CryptographicEngine 验证由 Node.js 加密 API 生成的签名哈希.因为 Verify 方法一直返回 false,所以我现在比较两种签名方法。当我使用两种系统签署一个简单的字符串时,我得到了不同的结果。

这是 Crypto JS 代码:

//Generate signer and hasher
var signature = crypto.createSign('RSA-SHA256');

var hasher = crypto.createHash("SHA256");    
hasher.update('mydata');

//Generate hash from data
hashresult = hasher.digest('base64');

signature.update(hashresult);

//Read private key
var inputkey = fs.readFileSync('private.pem');

//Sign Data
var result = signature.sign(inputkey, 'base64');

这里是 CryptographicEngine 代码:

IBuffer buffer = CryptographicBuffer.ConvertStringToBinary("mydata", BinaryStringEncoding.Utf8);

HashAlgorithmProvider hashAlgorithm = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);

IBuffer hashBuffer = hashAlgorithm.HashData(buffer);

var basehash = CryptographicBuffer.EncodeToBase64String(hashBuffer);

Debug.WriteLine("HASHED RESULT");
Debug.WriteLine(basehash);

//ENCRYPT SIGNATURE using GetPrivateKey to get base64 key without headers
string privatekey = await GetPrivateKey();
//Convert key to IBuffer
IBuffer privatekeybuf = CryptographicBuffer.DecodeFromBase64String(privatekey);

AsymmetricKeyAlgorithmProvider provider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaSignPkcs1Sha256);

CryptographicKey encryptKey = provider.ImportKeyPair(privatekeybuf, CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey);

var encryptedresult = CryptographicEngine.Sign(encryptKey, hashbuffer);

string resultencrypted = CryptographicBuffer.EncodeToBase64String(encryptedresult);

Debug.WriteLine("ENCRYPTED RESULT");
Debug.WriteLine(resultencrypted);

我已验证在 JS 和 UWP 中创建的两个哈希值是相等的。然而,两种签名方法的结果都不是。这些怎么可能不同呢?似乎编码是相等的。我在 UWP 中尝试过 Sign 和 SignHashedData,也尝试过各种其他编码。

有什么想法吗?

Node.js 的 Sign classCryptographicEngine.Sign 都需要未散列的数据。您不需要另外对数据进行哈希处理。您应该删除 Node.js 和 C# 中的双哈希。

RSA 加密和签名生成使用填充来提供任何有意义的安全性。有不同类型的填充是等效的,但有些是随机的。如果 Node.js 或 UWP 使用随机填充,则不能简单地比较签名结果。检查您的实现是否兼容的唯一方法是在一端签署一些数据并在另一端进行验证。然后在另一个方向重复。