Digital signature made in C# does not verify in C++

会有一股神秘感。 提交于 2019-12-21 19:45:52

问题


I have a C# application which digitally signs data using RSA. The code is as follows:

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportCspBlob(privateKeyBlob);

SHA1 sha1 = new SHA1CryptoServiceProvider();
sha1.ComputeHash(myData);

byte[] signature = rsa.SignHash(sha1.Hash, CryptoConfig.MapNameToOID("SHA1"));

I cannot verify the signature in C++. The code is as follows:

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);

The verification returns 0, GetLastError() returns 2148073478 "Invalid signature". The hashes are the same. I tried it with and without the CRYPT_NOHASHOID flag.

I tried signing the data in C++ (just to compare the results). I removed the CRYPT_VERIFYCONTEXT flag. But importing the private key BLOB fails with 1008 "An attempt was made to reference a token that does not exist". Generating a new key fails with the same error.


回答1:


After an exhausting byte by byte inspection, I got it working. There were two problems in the C# application.

1) I used new RSACryptoServiceProvider(RsaKeySize) to generate a key pair. The problem is that this generates a key pair for key exchange, not for signing. C# doesn't mind, but it caused trouble in the C++ program. The correct way for generating a key pair is:

CspParameters parameters = new CspParameters();
parameters.KeyNumber = (int)KeyNumber.Signature;

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(RsaKeySize, parameters);

2) The RSACryptoServiceProvider reverses its output (signatures, encrypted data). It is mentioned in the documentation. So you need to Array.Reverse() the computed signature before saving it.



来源:https://stackoverflow.com/questions/16015408/digital-signature-made-in-c-sharp-does-not-verify-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!