是否可以使用wincrypt进行HMAC?

我一直在尝试使用wincrypt / cryptoapi / Cryptography API执行直接的SHA256 HMAC:下一代(CNG),我真的很挣扎。 我的目标是Windows 8。

我找不到正确的方法或在任何地方找到任何例子。 我希望在C / C ++中执行以下操作,这在下面的C#中进行了演示

HMAC hashMaker = new HMACSHA256(Encoding.ASCII.GetBytes("SecretKey")); byte[] hash = hashMaker.ComputeHash(Encoding.ASCII.GetBytes("")); string hashStr = BitConverter.ToString(hash); 

它返回哈希:B2-42-48-67-5A-B8-03-87-5B-00-D7-8C-65-5A-AE-B7-92-E3-F9-27-40-C1-01 -A5-37-74-E1-65-51-9F-F6-6A。

有没有人成功使用cryptoapi执行直接HMAC?

感谢您提供Mgetz的信息。 我从来不知道BCrypt方法。 HMAC比wincrypt / cryptoapi的CryptHashData容易得多。 从使用SHA256使用散列的示例中,我能够创建HMAC代码。 您只需要将BCRYPT_ALG_HANDLE_HMAC_FLAG添加到BCryptOpenAlgorithmProvider的最后一个参数,并在调用BCryptCreateHash时包含该键。

这是完成的代码:

 #include  #include  #include  #pragma comment(lib, "bcrypt.lib") #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) #define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) void __cdecl wmain( int argc, __in_ecount(argc) LPWSTR *wargv) { BCRYPT_ALG_HANDLE hAlg = NULL; BCRYPT_HASH_HANDLE hHash = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; DWORD cbData = 0, cbHash = 0, cbHashObject = 0; PBYTE pbHashObject = NULL; PBYTE pbHash = NULL; CONST BYTE key[] = { "SecretKey" }; CONST BYTE message[] = { "" }; //open an algorithm handle if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider( &hAlg, BCRYPT_SHA256_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG))) { wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status); goto Cleanup; } //calculate the size of the buffer to hold the hash object if (!NT_SUCCESS(status = BCryptGetProperty( hAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbHashObject, sizeof(DWORD), &cbData, 0))) { wprintf(L"**** Error 0x%x returned by BCryptGetProperty\n", status); goto Cleanup; } //allocate the hash object on the heap pbHashObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbHashObject); if (NULL == pbHashObject) { wprintf(L"**** memory allocation failed\n"); goto Cleanup; } //calculate the length of the hash if (!NT_SUCCESS(status = BCryptGetProperty( hAlg, BCRYPT_HASH_LENGTH, (PBYTE)&cbHash, sizeof(DWORD), &cbData, 0))) { wprintf(L"**** Error 0x%x returned by BCryptGetProperty\n", status); goto Cleanup; } //allocate the hash buffer on the heap pbHash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbHash); if (NULL == pbHash) { wprintf(L"**** memory allocation failed\n"); goto Cleanup; } //create a hash if (!NT_SUCCESS(status = BCryptCreateHash( hAlg, &hHash, pbHashObject, cbHashObject, (PBYTE)key, sizeof(key)-1, 0))) { wprintf(L"**** Error 0x%x returned by BCryptCreateHash\n", status); goto Cleanup; } //hash some data if (!NT_SUCCESS(status = BCryptHashData( hHash, (PBYTE)message, sizeof(message)-1, 0))) { wprintf(L"**** Error 0x%x returned by BCryptHashData\n", status); goto Cleanup; } //close the hash if (!NT_SUCCESS(status = BCryptFinishHash( hHash, pbHash, cbHash, 0))) { wprintf(L"**** Error 0x%x returned by BCryptFinishHash\n", status); goto Cleanup; } printf("The hash is: "); for (DWORD i = 0; i < cbHash; i++) { printf("%2.2X-", pbHash[i]); } Cleanup: if (hAlg) { BCryptCloseAlgorithmProvider(hAlg, 0); } if (hHash) { BCryptDestroyHash(hHash); } if (pbHashObject) { HeapFree(GetProcessHeap(), 0, pbHashObject); } if (pbHash) { HeapFree(GetProcessHeap(), 0, pbHash); } };