Mgetz에 감사드립니다. BCrypt 메서드 집합에 대해서는 전혀 몰랐습니다. wincrypt/cryptoapi의 CryptHashData보다 HMAC가 훨씬 쉽습니다. hashing using SHA256을 사용하는 예에서 HMAC 코드를 만들 수있었습니다. BCryptOpenAlgorithmProvider의 마지막 매개 변수에 BCRYPT_ALG_HANDLE_HMAC_FLAG을 추가하고 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);
}
};
= (http://msdn.microsoft.com/en-us/library/windows/desktop/aa376217 (V이 [SHA256의 사용 예]가 vs.85) .aspx) 당신이해야 할 일은 바닐라 SHA256의 알고리즘을 ['BCRYPT_SP800108_CTR_HMAC_ALGORITHM'] (http://msdn.microsoft.com/en-us/library/windows/desktop/aa375534 v = vs.85) .aspx)를 사용하십시오. 위의 예제에서 알고리즘과 해시를 만드는 예제에서 * 알고리즘 *을 변경해야합니다. 또한 XML의 ASCII를 원하지 않으면 특정 문자가 대체 될 수 있습니다. – Mgetz
예 XML 용 ASCII를 사용하는 것이 좋지 않을 것이라고 동의합니다. 일부 문자는 잘못 인코딩됩니다. UFT16보다 c가 쉽게 변환 될 수 있음을 알았 기 때문에이 내용이 예제 콘텐츠였습니다. –