使用C#生成的数字签名无法在C ++中进行validation

我有一个C#应用程序,它使用RSA对数据进行数字签名。 代码如下:

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.ImportCspBlob(privateKeyBlob); SHA1 sha1 = new SHA1CryptoServiceProvider(); sha1.ComputeHash(myData); byte[] signature = rsa.SignHash(sha1.Hash, CryptoConfig.MapNameToOID("SHA1")); 

我无法在C ++中validation签名。 代码如下:

 HCRYPTPROV cryptProvider; CryptAcquireContext(&cryptProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); // PROV_RSA_SIG does not work HCRYPTKEY publicKey; CryptImportKey(cryptProvider, publicKeyBlob, publicKeyBlobLength, 0, 0, &publicKey); HCRYPTHASH hash; CryptCreateHash(cryptProvider, CALG_SHA1, 0, 0, &hash); CryptHashData(hash, myData, myDataLength, 0); BOOL isSigOk = CryptVerifySignature(hash, signature, signatureLength, publicKey, NULL, CRYPT_NOHASHOID); 

validation返回0, GetLastError()返回2148073478“无效签名”。 哈希是一样的。 我尝试使用和不使用CRYPT_NOHASHOID标志。

我尝试用C ++签名数据(只是为了比较结果)。 我删除了CRYPT_VERIFYCONTEXT标志。 但导入私钥BLOB失败1008“尝试引用不存在的令牌”。 生成新密钥失败并出现相同的错误。

在逐字节检查后,我得到了它的工作。 C#应用程序中存在两个问题。

1)我使用new RSACryptoServiceProvider(RsaKeySize)来生成密钥对。 问题是,这会为密钥交换生成密钥对,而不是签名。 C#并不介意,但它在C ++程序中引起了麻烦。 生成密钥对的正确方法是:

 CspParameters parameters = new CspParameters(); parameters.KeyNumber = (int)KeyNumber.Signature; RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(RsaKeySize, parameters); 

2) RSACryptoServiceProvider反转其输出(签名,加密数据)。 它在文档中提到。 因此在保存之前需要Array.Reverse()计算出的签名。