I\'m trying to use the winapi crypto api to get a base64 encoded hash. I copied and modified to get the function below. I got it from here mostly - https://msdn.microsoft.co
the function work correct, not need fix it. but you not take to account what is key here used for HMAC
- not direct your string key, but first, based on your string key, RC4
key created and HMAC
calculated for this binary RC4
key.
different keys -> different hash.
windows not let direct use string keys. it algorithm is better - first convert weak string key to more strong binary key. however if you want use string key and got result for it - can use code like this:
#define BLOCK_SIZE 64
BOOL hmac(PCSTR key, PCSTR message, ALG_ID Algid)
{
UCHAR i_key_pad[BLOCK_SIZE], o_key_pad[BLOCK_SIZE];
HCRYPTPROV hProv;
HCRYPTHASH hHash;
ULONG len = (ULONG)strlen(key), cb;
BOOL f;
if (f = CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (len > BLOCK_SIZE)
{
if (f = CryptCreateHash(hProv, Algid, 0, 0, &hHash))
{
f = CryptHashData(hHash, (PBYTE)key, len, 0) &&
CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&len, &(cb = sizeof(len)), 0) &&
CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)(key = (PCSTR)alloca(len)), &len, 0);
CryptDestroyHash(hHash);
}
}
if (f)
{
ULONG i = BLOCK_SIZE;
do
{
UCHAR c = --i < len ? key[i] : 0;
i_key_pad[i] = 0x36 ^ c;
o_key_pad[i] = 0x5c ^ c;
} while (i);
if (f = CryptCreateHash(hProv, Algid, 0, 0, &hHash))
{
f = CryptHashData(hHash, i_key_pad, sizeof(i_key_pad), 0) &&
CryptHashData(hHash, (PBYTE)message, (ULONG)strlen(message), 0) &&
CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&len, &(cb = sizeof(len)), 0) &&
CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)(key = (PCSTR)alloca(len)), &len, 0);
CryptDestroyHash(hHash);
if (f && (f = CryptCreateHash(hProv, Algid, 0, 0, &hHash)))
{
f = CryptHashData(hHash, o_key_pad, sizeof(o_key_pad), 0) &&
CryptHashData(hHash, (PBYTE)key, len, 0) &&
CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)key, &len, 0);
CryptDestroyHash(hHash);
if (f && len)
{
DbgPrint("\nThe hash is: ");
do
{
DbgPrint("%02x", (UCHAR)*key++);
} while (--len);
DbgPrint("\n");
}
}
}
}
CryptReleaseContext(hProv, 0);
}
return f;
}
//The hash is: 2088df74d5f2146b48146caf4965377e9d0be3a4
hmac("key","message", CALG_SHA1);