SecurityXploded Blog

CryptoCode: Generate MD5 Hash using Windows Cryptography Library

Here I have decided to put together series of Crypto sample using Windows Cryptography functions as well as OpenSSL library. This is to make it easier for myself as well as others to find ready to use cryptography code examples.

Though some of these code samples are present some where on the net, I am putting it here together to have them at one place. The code presented here is more or less final and you can directly integrate it in your projects with no or minimal changes.

To begin with, today I am writing sample program on generating popular Md5 Hash using Windows Cryptography Functions such as CryptCreateHash, CryptHashData & CryptGetHashParam etc.

.

//
//  Compute the MD5 checksum for input buffer
//
BOOL GetMD5Hash(char *buffer,             //input buffer
                 DWORD dwBufferSize,       //input buffer size
                 BYTE *byteFinalHash,      //ouput hash buffer
                 DWORD *dwFinalHashSize    //input/output final buffer size
)
{
 DWORD dwStatus = 0;
 BOOL bResult = FALSE;
 HCRYPTPROV hProv = 0;
 HCRYPTHASH hHash = 0;
 //BYTE *byteHash;
 DWORD cbHashSize = 0;

 // Get handle to the crypto provider
 if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
 {
 printf("\nCryptAcquireContext failed, Error=0x%.8x", GetLastError());
 return FALSE;
 }

 //Specify the Hash Algorithm here
 if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
 {
 printf("\nCryptCreateHash failed,  Error=0x%.8x", GetLastError());
 goto EndHash;
 }

 //Create the hash with input buffer
 if (!CryptHashData(hHash, (const BYTE*) buffer, dwBufferSize, 0))
 {
 printf("\nCryptHashData failed,  Error=0x%.8x", GetLastError());
 goto EndHash;
 }

 //Get the final hash size 
 DWORD dwCount = sizeof(DWORD);
 if(!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&cbHashSize, &dwCount, 0)) 
 {
 printf("\nCryptGetHashParam failed, Error=0x%.8x", GetLastError());
 goto EndHash;
 }

 //check if the output buffer is enough to copy the hash data
 if( *dwFinalHashSize < cbHashSize )
 {
 printf("\nOutput buffer (%d) is not sufficient, Required Size = %d",
                        *dwFinalHashSize, cbHashSize);
 goto EndHash;
 }

 //Now get the computed hash 
 if (CryptGetHashParam(hHash, HP_HASHVAL, byteFinalHash, dwFinalHashSize, 0))
 {
 printf("\n********** Hash Computed successfully ");
 bResult = TRUE; 
 }
 else
 {
 printf("\nCryptGetHashParam failed,  Error=0x%.8x", GetLastError());
 }



EndHash:

 if( hHash )
 CryptDestroyHash(hHash);

 if( hProv )
 CryptReleaseContext(hProv, 0);

 return bResult; 
}   

.

You can put the above function anywhere in your code and then call it using below code snippet,

BYTE byteHashbuffer[256];
DWORD dwFinalHashSize= 256;

GetMD5Hash("test", 4, byteHashbuffer, &dwFinalHashSize);.

.

Above code is simple and more or less self explanatory.  Here we use CryptCreateHash function specifying the algorithm CALG_MD5.  You can also specify CALG_MD2 or CALG_MD4 for older versions of same Hash family.  Next we hash the input buffer CryptHashData to generate the MD5 hash.  Once hash is generated we can get its length through CryptGetHashParam function by specifying flag as HP_HASHSIZE.  This can be used for verification of buffer size or allocate fresh buffer.  Next we call CryptGetHashParam again with flag as HP_HASHVAL to get the final MD5 hash data.

.

In the next blog post, I will be writing about generation of hash using SHA family algorithm such as SHA1, SHA256 etc.

.

See Also

CryptoCode: Index of All Crypto Articles

Leave a Reply