gpt4 book ai didi

c++ - MSDN HMAC-SHA1 示例不工作

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:45:43 25 4
gpt4 key购买 nike

使用此处找到的 CryptoAPI 创建 HMAC 步骤:http://msdn.microsoft.com/en-us/library/Aa379863

  • 计算 HMAC

    1. 获取指向 Microsoft 加密服务提供程序的指针(CSP) 通过调用 CryptAcquireContext。
    2. 通过调用创建 HMAChash 对象的句柄CryptCreateHash。在 Algid 参数中传递 CALG_HMAC。通过hKey 参数中对称 key 的句柄。这个对称 key 是用于计算 HMAC 的 key 。
    3. 通过调用指定要使用的散列类型将 dwParam 参数设置为值的 CryptSetHashParamHP_HMAC_INFO。 pbData 参数必须指向一个已初始化的HMAC_INFO 结构。
    4. 调用 CryptHashData 开始计算数据的 HMAC。这第一次调用 CryptHashData 导致键值被组合使用XOR 运算符与内部字符串和数据。的结果XOR 运算被散列,然后是 HMAC 的目标数据(由调用中传递的 pbData 参数指向CryptHashData) 被散列。如有必要,随后调用然后可以使 CryptHashData 完成目标的散列数据。
    5. 调用 CryptGetHashParam 并将 dwParam 参数设置为HP_HASHVAL。此调用导致内部哈希完成并且要使用 XOR 与 key 组合的外部字符串。结果异或运算被哈希,然后是内层哈希的结果(在上一步中完成)被散列。然后是外部哈希完成并在 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)?

  • 为什么把哈希算法改成SHA1

  • 为什么您不再在 ErrorExit 上退出(只有这样才能防止崩溃而不是正确的错误消息)

  • 您使用 CryptImportKey 而不是 CryptDeriveKey —— MSDN 上的示例中甚至不存在这样的东西。 CryptImportKey 是调用失败并显示 0x80090005 (NTE_BAD_DATA),这不可能是巧合。您的 CSP 不支持该 key !

  • 为此,您需要 key 访问权限,因此您至少需要将 CRYPT_VERIFY_CONTEXT 更改为其他内容(不知道是什么);我尝试使用

.

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

它在运行时确实崩溃了(没有参数),但这可能是 wine 不兼容(或者我没有阅读源代码以了解它的作用:))

关于c++ - MSDN HMAC-SHA1 示例不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7547791/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com