【发布时间】:2014-02-06 00:13:11
【问题描述】:
我的要求是验证我之前在 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 与 Native 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 ! 你能看看我的代码并指出我的错误吗
谢谢。
【问题讨论】:
-
我强烈怀疑你不应该反转散列......它只是一个字节序列,而不是被视为小端或大端的数字......
-
@JonSkeet 请参考这个 MSDN 链接,如果它可以帮助msdn.microsoft.com/en-us/library/…
-
有趣,但这说明它是用于加密而不是签名。您是否至少尝试过不扭转它?
-
对。顺便说一句,您的“C#”代码似乎是 C# 和 VB 的混合体,并且您的 C++ 代码似乎无效(例如,查看 ReadFile 的参数)。您能否发布简短但完整且有效的 C# 和 C++ 程序来演示该问题?
-
如果没有真正的代码,将很难重现问题。通过简短而完整的计划,我们可能能够更轻松地为您提供帮助。
标签: c# c++ winapi encryption hash