使用此处找到的CryptoAPI创建HMAC步骤:http://msdn.microsoft.com/en-us/library/Aa379863
(CSP),方法是调用CryptAcquireContext。
CryptCreateHash。在Algid参数中传递CALG_HMAC。通过
hKey参数中对称 key 的句柄。这个对称 key
是用于计算HMAC的 key 。
将dwParam参数设置为值的CryptSetHashParam
HP_HMAC_INFO。 pbData参数必须指向已初始化
HMAC_INFO结构。
首次调用CryptHashData会导致键值使用
带有内部字符串和数据的XOR运算符。的结果
对XOR操作进行哈希处理,然后将HMAC的目标数据
(由传递给的调用中的pbData参数指向
CryptHashData)进行哈希处理。如有必要,随后致电
然后可以使CryptHashData完成目标的散列
数据。
HP_HASHVAL。此调用导致内部哈希完成,并且
要使用XOR与键组合的外部字符串。结果
对XOR操作进行哈希处理,然后进行内部哈希处理的结果
(在上一步中完成)进行哈希处理。然后是外部哈希
完成并在pbData参数中返回,并在
dwDataLen参数。
我不能,为了我的一生,请继续努力。我已经按顺序完成了所有步骤,但仍然无法运行我的程序。运行时出现错误:
Error in CryptImportKey 0x8009007
Error in CryptCreatHash 0x8009003
Error in CryptSetHashParam 0x00000057
Error in CryptHashData 0x00000057
Error in CryptGetHashParam 0x00000057
有人可以帮忙吗?
#include <iostream>
#include <windows.h>
#include <wincrypt.h>
using namespace std;
#define CALG_HMAC CALG_SHA1
int main()
{
//--------------------------------------------------------------------
// Declare variables.
HCRYPTPROV hProv = NULL;
HCRYPTHASH hHash = NULL;
HCRYPTKEY hKey = NULL;
BYTE DesKeyBlob[] = { 0x70,0x61,0x73,0x73,0x77,0x6F,0x72,0x64 };
HCRYPTHASH hHmacHash = NULL;
PBYTE pbHash = NULL;
DWORD dwDataLen = 20;
BYTE Data[] = {0x6D,0x65,0x73,0x73,0x61,0x67,0x65};
HMAC_INFO HmacInfo;
//--------------------------------------------------------------------
// Zero the HMAC_INFO structure
ZeroMemory(&HmacInfo, sizeof(HmacInfo));
HmacInfo.HashAlgid = CALG_HMAC;
HmacInfo.pbInnerString = (BYTE*)0x36;
HmacInfo.cbInnerString = 0;
HmacInfo.pbOuterString = (BYTE*)0x5C;
HmacInfo.cbOuterString = 0;
// Step 1
if (!CryptAcquireContext(
&hProv, // handle of the CSP
NULL, // key container name
NULL, // CSP name
PROV_RSA_FULL, // provider type
CRYPT_VERIFYCONTEXT)) // no key access is requested
{
printf(" Error in AcquireContext 0x%08x \n",
GetLastError());
}
//--------------------------------------------------------------------
//Step 2
//in step two, we need the hash key used to be imported?
//imports the key used... as hKey1
if(!CryptImportKey(
hProv,
DesKeyBlob,
sizeof(DesKeyBlob),
0,
CRYPT_EXPORTABLE,
&hKey ))
{
printf("Error in !CryptImportKey 0x%08x \n",
GetLastError());
}
if (!CryptCreateHash(
hProv, // handle of the CSP
CALG_HMAC, // hash algorithm to use
hKey, // hash key this shoudl point to a key used to compute the HMAC?
0, // reserved
&hHmacHash // address of hash object handle
)){
printf("Error in CryptCreateHash 0x%08x \n",
GetLastError());
}
// Step 3
if (!CryptSetHashParam(
hHmacHash,//hProv,//hHash,//hHmacHash, // handle of the HMAC hash object
HP_HMAC_INFO, // setting an HMAC_INFO object
(BYTE*)&HmacInfo, // the HMAC_INFO object
0)) // reserved
{
printf("Error in CryptSetHashParam 0x%08x \n",
GetLastError());
}
//Step 4
if (!CryptHashData(
hHmacHash, // handle of the HMAC hash object
Data, // message to hash
sizeof(Data), // number of bytes of data to add
0)) // flags
{
printf("Error in CryptHashData 0x%08x \n",
GetLastError());
}
//Step 5
if (!CryptGetHashParam(
hHmacHash, // handle of the HMAC hash object
HP_HASHVAL, // query on the hash value
pbHash, // pointer to the HMAC hash value
&dwDataLen, // length, in bytes, of the hash
0))
{
printf("Error in CryptGetHashParam 0x%08x \n", GetLastError());
}
// Print the hash to the console.
printf("The hash is: ");
for(DWORD i = 0 ; i < dwDataLen ; i++)
{
printf("%2.2x ",pbHash[i]);
}
printf("\n");
int a;
std::cin >> a;
return 0;
}
最佳答案
您可能(?1)需要指定要使用的哈希算法。
#define CALG_HMAC CALG_SHA1 // or CALG_MD5 etc
编辑
dwDataLen = 20
(而不是0)? CryptImportKey
而不是CryptDeriveKey
-MSDN上的示例中甚至不存在此类内容。 CryptImportKey是因0x80090005(NTE_BAD_DATA)而失败的调用,这绝非偶然。您的CSP不支持该 key ! 。
if (!CryptAcquireContext(
&hProv,
NULL,
MS_STRONG_PROV, // allow 2048 bit keys, in case you need it
PROV_RSA_FULL,
CRYPT_MACHINE_KEYSET)) // just a guess
现在我的程序生成
0x80090016: Keyset does not exist
。这可能仅仅是因为我没有该键集,或者是因为我在Linux上的Wine下运行。希望这可以帮助。
1在Linux上使用以下命令进行编译:
i586-mingw32msvc-g++ -m32 -O2 -g test.cpp -o test.exe
它在运行时确实崩溃了(没有参数),但这可能是酒不兼容的(或者我还没有阅读源代码以了解它的作用的事实:))