I recently had the need to generate HMACs with AutoHotkey and I found almost all the work was already done in the old forum by user manonstreet. I made it compatible with x64 and fixed a couple of minor mistakes and this is the result:
Code: Select all
HMAC(ByRef HashVal, ByRef sData, nDataSize, ByRef sKey, nKeySize, sHashAlg = "SHA256")
{
CALG_SHA_512 := 1 + CALG_SHA_384 := 1 + CALG_SHA_256 := 8 + CALG_SHA1 := 1 + CALG_MD5 := 0x00008003
Static PROV_RSA_FULL := 0x01,
CUR_BLOB_VERSION := 0x02,
PLAINTEXTKEYBLOB := 0x08,
CRYPT_VERIFYCONTEXT := 0xF0000000,
CALG_RC2 := 0x6602,
CALG_HMAC := 0x8009,
HP_HMAC_INFO := 0x05,
HP_HASHVAL := 0x02,
CRYPT_IPSEC_HMAC_KEY := 0x0100
VarSetCapacity(HmacInfo, 4 * A_PtrSize, 0) ; HMAC_INFO struct, see http://msdn.com/library/aa382480
NumPut(CALG_%sHashAlg%, HmacInfo, 0, "UInt") ; selects hashing algorithm, the rest is zero so default strings are used
nKeyBlobSize := 12 + nKeySize
VarSetCapacity(keyBlob, nKeyBlobSize, 0) ; BLOBHEADER struct, see http://msdn.com/library/aa387453
NumPut(PLAINTEXTKEYBLOB, keyBlob, 0, "Char") ; PLAINTEXTKEYBLOB struct, http://msdn.com/library/jj650836
NumPut(CUR_BLOB_VERSION, keyBlob, 1, "Char")
NumPut(CALG_RC2, keyBlob, 4, "UInt")
NumPut(nKeySize, keyBlob, 8, "Char")
DllCall("RtlMoveMemory", "UInt", &keyBlob + 12, "UInt", &sKey, "Int", nKeySize) ; see http://msdn.com/library/ff562030
; see steps at http://msdn.com/library/aa379863 and C++ example at http://msdn.com/library/aa382379
If (DllCall("advapi32\CryptAcquireContext", "UIntP", hProv, "UInt", 0, "UInt", 0, "UInt", PROV_RSA_FULL, "UInt", CRYPT_VERIFYCONTEXT)) {
If (DllCall("advapi32\CryptImportKey", "UInt", hProv, "UInt", &keyBlob, "UInt", nKeyBlobSize, "UInt", 0, "UInt", CRYPT_IPSEC_HMAC_KEY, "UIntP", hKey)) {
If (DllCall("advapi32\CryptCreateHash", "UInt", hProv, "UInt", CALG_HMAC, "UInt", hKey, "UInt", 0, "UIntP", hHmacHash)) {
If (DllCall("advapi32\CryptSetHashParam", "UInt", hHmacHash, "UInt", HP_HMAC_INFO, "UInt", &HmacInfo, "UInt", 0)) {
If (DllCall("advapi32\CryptHashData", "UInt", hHmacHash, "UInt", &sData, "UInt", nDataSize, "UInt", 0)) {
If (DllCall("advapi32\CryptGetHashParam", "UInt", hHmacHash, "UInt", HP_HASHVAL, "UInt", 0, "UIntP", nHashSize, "UInt", 0)) { ; hash size
VarSetCapacity(HashVal, nHashSize, 0)
DllCall("advapi32\CryptGetHashParam", "UInt", hHmacHash, "UInt", HP_HASHVAL, "UInt", &HashVal, "UIntP", nHashSize, "UInt", 0) ; hash value
}
}
}
DllCall("advapi32\CryptDestroyHash", "UInt", hHmacHash)
}
DllCall("advapi32\CryptDestroyKey", "UInt", hKey)
}
DllCall("advapi32\CryptReleaseContext", "UInt", hProv, "UInt", 0)
}
Return nHashSize
}
Code: Select all
Wide2UTF8(sInput, ByRef Output)
{
nOutputSize := StrPut(sInput, "UTF-8")
VarSetCapacity(Output, nOutputSize)
StrPut(sInput, &Output, nOutputSize, "UTF-8")
Return nOutputSize-1
}
http://dl.dropboxusercontent.com/u/7416 ... tation.ahk
As manonstreet more than three years ago, I hope someone finds this useful somehow
Regards,
Antonio