是否可以使用wincrypt进行HMAC? [英] Is it possible to do a HMAC with wincrypt?
问题描述
我一直在尝试使用wincrypt/cryptoapi/Cryptography API:下一代(CNG)执行简单的SHA256 HMAC,我真的很挣扎.我的目标是Windows 8.
I've been trying to perform a straight forward SHA256 HMAC using wincrypt/cryptoapi/Cryptography API: Next Generation (CNG) and i'm really struggling. My target is Windows 8.
我找不到正确的方法或在任何地方都找不到任何示例.我希望在C/C ++中执行以下操作,下面的C#演示了该操作
I can not find the correct methods or find any examples anywhere. I am looking to do the following in C/C++, that is demonstrated in C# below
HMAC hashMaker = new HMACSHA256(Encoding.ASCII.GetBytes("SecretKey"));
byte[] hash = hashMaker.ComputeHash(Encoding.ASCII.GetBytes("<SomeXmlData />"));
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.
it returns the 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吗?
Has anybody succeeded to perform a straight forward HMAC using the cryptoapi?
推荐答案
感谢您提供Mgetz信息.我从不知道BCrypt方法集.对于HMAC而言,它比wincrypt/cryptoapi的CryptHashData容易得多.从使用使用SHA256进行哈希处理我能够创建HMAC代码.您只需要添加 BCRYPT_ALG_HANDLE_HMAC_FLAG 标记为BCryptOpenAlgorithmProvider的最后一个参数,并在对
Thank you for the information Mgetz. I never knew about the BCrypt set of methods. It is a lot easier for HMAC than CryptHashData of the wincrypt/cryptoapi. From the example of using hashing using SHA256 I was able to create the HMAC code. You only need to add BCRYPT_ALG_HANDLE_HMAC_FLAG to the last parameter of BCryptOpenAlgorithmProvider and include the key in the call to BCryptCreateHash.
这是完整的代码:
#include <windows.h>
#include <stdio.h>
#include <bcrypt.h>
#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[] = { "<SomeXmlData />" };
//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);
}
};
这篇关于是否可以使用wincrypt进行HMAC?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!