Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compute MD5 hash value by c++ WinAPI

My C++ app needs to compute an MD5 hash value. Currently, it is done by OpenSSL, and I want to use WinAPI - to avoid dependencies on external libraries.

I wrote this code:

HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hHash = NULL;
HCRYPTHASH hHexHash = NULL;
HASH HA1;
HASHHEX HA1HEX;
DWORD data = HASHLEN;

// Get a handle to a cryptography provider context.
if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0))
{
    goto err;
}

// Acquire a hash object handle.
if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash))
{
    goto err;
}

CryptHashData(hHash, (const BYTE *)str, strlen(str), 0);

now, the strange thing is that sometimes it works well, but in other times the CryptAcquireContext returns NTE_BAD_KEYSET error, that according to MSDN :

The key container could not be opened. A common cause of this error is that the key container does not exist. To create a key container, call CryptAcquireContext using the CRYPT_NEWKEYSET flag. This error code can also indicate that access to an existing key container is denied. Access rights to the container can be granted by the key set creator by using CryptSetProvParam.

Blockquote

Now my questions are:

  1. If I call CryptSetProvParam, what exactly does it do? Is it normal that simple application changes the OS settings?
  2. Is there any less difficult way to compute MD5 in C++ windows?

I'll appreciate if someone gives me good advice on what to do.
Thanks.

like image 399
RRR Avatar asked Nov 06 '12 17:11

RRR


1 Answers

So, I found an example that does what you want at http://msdn.microsoft.com/en-us/library/aa382380%28VS.85%29.aspx

Looking at their code, the difference I see is this line:

Theirs: CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)

Yours: CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)

So, reading up on that flag, I find this information:

CRYPT_VERIFYCONTEXT: This option is intended for applications that are using ephemeral keys, or applications that do not require access to persisted private keys, such as applications that perform only hashing, encryption, and digital signature verification. Only applications that create signatures or decrypt messages need access to a private key. In most cases, this flag should be set.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa379886%28v=vs.85%29.aspx

So, it looks like you are trying to get access to information you don't need, and the request is denied. So the best option is to tell Windows you don't need that information by including that flag.

like image 179
Patrick M Avatar answered Sep 24 '22 12:09

Patrick M