2014-03-03 9 views
2

저는 wincrypt/cryptoapi/Cryptography API : 차세대 (CNG)를 사용하여 직선적 인 SHA256 HMAC를 수행하려고 노력해 왔으며 정말 고심하고 있습니다. 내 목표는 Windows 8입니다.wincrypt로 HMAC를 할 수 있습니까?

올바른 방법을 찾을 수 없으며 어디서나 예제를 찾을 수 없습니다. 나는 C/C++로 다음과 같은 작업을 수행 할 찾고, 그는

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

아래 C#으로 설명된다 그것은 해시 반환 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를 수행하는 데 성공 했습니까?

+1

= (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

+0

예 XML 용 ASCII를 사용하는 것이 좋지 않을 것이라고 동의합니다. 일부 문자는 잘못 인코딩됩니다. UFT16보다 c가 쉽게 변환 될 수 있음을 알았 기 때문에이 내용이 예제 콘텐츠였습니다. –

답변

4

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); 
    } 
};