为什么Node.js的标志和CryptographicEngine标志结果之间有区别?

时间:2016-01-12 20:33:07

标签: c# node.js cryptography digital-signature uwp

我正在尝试使用 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,并尝试了其他各种编码。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

Node.js Sign classCryptographicEngine.Sign都期望未加数据的数据。您不需要另外散列数据。您应该删除Node.js和C#中的双重散列。

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