我的要求是验证我之前在VB.Net中签名的C ++应用程序中的签名哈希值。
我将简要解释一下我为实现它所做的一切...... 首先,我使用CspParameters.KeyNumber value =“Signature”创建了一个私钥/公钥对,并将其CspBlob导出到文件“KeyPair.txt”,以便在我的C ++程序中使用公钥。
Dim str As testData= "Hello World"
Dim Hash() As Byte = HashAlgorithm.Create("SHA1").ComputeHash(testData)
Hash = RSA.SignHash(Hash, CryptoConfig.MapNameToOID("SHA1"))
Array.Reverse(Hash)
并以相反的顺序将签名哈希保存在文件“Signature.txt”中,以便VB.Net与原生CAPI兼容(Big Endian到Little Endian)。
2)。 另一端(C ++程序)......
首先,我计算了testData“Hello World”的SHA1,然后使用下面的代码来验证签名。
BYTE* Message_Digest_SHA1 = SHA1("Hello World");
BYTE* pbBlob = ReadFile("KeyPair.txt");
int pbBlobLen = GetFileLen("KeyPair.txt");
BYTE* pbSignature = ReadFile("Signature.txt");
int pbSignatureLen = GetFileLen("Signature.txt");
if (!CryptAcquireContext(&hProv, NULL, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
//Error checking omitted !
}
if (pbBlob) {
if (!CryptImportKey(hProv, pbBlob, pbBlobLen , 0, 0, &hPubKey))
return FALSE;
}
HCRYPTHASH hHash;
if(CryptCreateHash(
hProv,
CALG_SHA1,
0,
0,
&hHash))
{
printf("The hash object has been recreated. \n");
}
else
{
// Error
}
if(CryptHashData(
hHash,
Message_Digest_SHA1 ,
20, // length of message digest
0))
{
printf("The new hash has been created.\n");
}
else
{
//Error
}
if(CryptVerifySignature(
hHash,
pbSignature,
pbSignatureLen ,
hPubKey,
NULL,
0))
{
printf("The signature has been verified.\n");
}
else
{
DWORD error = GetLastError(); // 2148073478 in HEX 0x80090006 NTE_BAD_SIGNATURE
printf("Signature not validated!\n");
}
if(hHash)
CryptDestroyHash(hHash);
但是,CryptVerifySignature失败了NTE_BAD_SIGNATURE! 你能不能看看我的代码并指出我的错误
谢谢。
答案 0 :(得分:1)
你似乎哈希两次。进入
BYTE* Message_Digest_SHA1 = SHA1("Hello World");
然后再次
CryptHashData(hHash, Message_Digest_SHA1, 20,0)
我怀疑你只需要哈希一次。我建议删除第一个,因为签名方法需要引用哈希对象。提供"Hello World"
的正确的二进制编码作为数据。