I thought this may be of interest.
001 #include <iostream>
002 #include "windows.h"
003 #include <wincrypt.h>
004
005 #ifndef CALG_HMAC
006 #define CALG_HMAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HMAC)
007 #endif
008
009 #ifndef CRYPT_IPSEC_HMAC_KEY
010 #define CRYPT_IPSEC_HMAC_KEY 0x00000100
011 #endif
012
013 #pragma comment(lib, "crypt32.lib")
014
015 using namespace std;
016
017 char * HMAC(char * str, char * password, DWORD AlgId);
018
019
020 typedef struct _my_blob{
021 BLOBHEADER header;
022 DWORD len;
023 BYTE key[0];
024 }my_blob;
025
026
027 int main(int argc, _TCHAR* argv[])
028 {
029
030 char * hash_sha1 = HMAC("ROSDEVIL", "password", CALG_SHA1);
031 char * hash_md5 = HMAC("ROSDEVIL", "password", CALG_MD5);
032
033 cout<<"Hash HMAC-SHA1: "<<hash_sha1<<" ( "<<strlen(hash_sha1)<<" )"<<endl;
034 cout<<"Hash HMAC-MD5: "<<hash_md5<<" ( "<<strlen(hash_md5)<<" )"<<endl;
035
036 cin.get();
037 return 0;
038 }
039
040 char * HMAC(char * str, char * password, DWORD AlgId = CALG_MD5){
041
042 HCRYPTPROV hProv = 0;
043 HCRYPTHASH hHash = 0;
044 HCRYPTKEY hKey = 0;
045 HCRYPTHASH hHmacHash = 0;
046 BYTE * pbHash = 0;
047 DWORD dwDataLen = 0;
048 HMAC_INFO HmacInfo;
049
050 int err = 0;
051
052 ZeroMemory(&HmacInfo, sizeof(HmacInfo));
053
054 if (AlgId == CALG_MD5){
055 HmacInfo.HashAlgid = CALG_MD5;
056 pbHash = new BYTE[16];
057 dwDataLen = 16;
058 }else if(AlgId == CALG_SHA1){
059 HmacInfo.HashAlgid = CALG_SHA1;
060 pbHash = new BYTE[20];
061 dwDataLen = 20;
062 }else{
063 return 0;
064 }
065
066 ZeroMemory(pbHash, sizeof(dwDataLen));
067 char * res = new char[dwDataLen * 2];
068
069 my_blob * kb = NULL;
070 DWORD kbSize = sizeof(my_blob) + strlen(password);
071
072 kb = (my_blob*)malloc(kbSize);
073 kb->header.bType = PLAINTEXTKEYBLOB;
074 kb->header.bVersion = CUR_BLOB_VERSION;
075 kb->header.reserved = 0;
076 kb->header.aiKeyAlg = CALG_RC2;
077 memcpy(&kb->key, password, strlen(password));
078 kb->len = strlen(password);
079
080
081 if (!CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL,CRYPT_VERIFYCONTEXT | CRYPT_NEWKEYSET)){
082 err = 1;
083 goto Exit;
084 }
085
086
087 if (!CryptImportKey(hProv, (BYTE*)kb, kbSize, 0, CRYPT_IPSEC_HMAC_KEY, &hKey)){
088 err = 1;
089 goto Exit;
090 }
091
092 if (!CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHmacHash)){
093 err = 1;
094 goto Exit;
095 }
096
097
098 if (!CryptSetHashParam(hHmacHash, HP_HMAC_INFO, (BYTE*)&HmacInfo, 0)){
099 err = 1;
100 goto Exit;
101 }
102
103 if (!CryptHashData(hHmacHash, (BYTE*)str, strlen(str), 0)){
104 err = 1;
105 goto Exit;
106 }
107
108 if (!CryptGetHashParam(hHmacHash, HP_HASHVAL, pbHash, &dwDataLen, 0)){
109 err = 1;
110 goto Exit;
111 }
112
113 ZeroMemory(res, dwDataLen * 2);
114 char * temp;
115 temp = new char[3];
116 ZeroMemory(temp, 3);
117 for (unsigned int m = 0; m < dwDataLen; m++){
118 sprintf(temp, "%2x", pbHash[m]);
119 if (temp [1] == ' ') temp [1] = '0'; // note these two: they are two CORRECTIONS to the conversion in HEX, sometimes the Zeros are
120 if (temp [0] == ' ') temp [0] = '0'; // printed with a space, so we replace spaces with zeros; (this error occurs mainly in HMAC-SHA1)
121 sprintf(res,"%s%s", res,temp);
122 }
123
124 delete [] temp;
125
126 Exit:
127 free(kb);
128 if(hHmacHash)
129 CryptDestroyHash(hHmacHash);
130 if(hKey)
131 CryptDestroyKey(hKey);
132 if(hHash)
133 CryptDestroyHash(hHash);
134 if(hProv)
135 CryptReleaseContext(hProv, 0);
136
137
138 if (err == 1){
139 delete [] res;
140 return "";
141 }
142
143 return res;
144 }
145 //Note: using HMAC-MD5 you could perform the famous CRAM-MD5 used to authenticate
146 //smtp servers.
credits ?
where'd you get it ?
i am no C guy, but.....
the first 3 lines look a little out of whack, to me :biggrin:
001 #include <iostream>
002 #include "windows.h"
003 #include <wincrypt.h>
ROSDEVIL wrote it. It's in the code.
:t
Quote from: dedndave on March 10, 2013, 12:31:46 AM
i am no C guy, but.....
the first 3 lines look a little out of whack, to me :biggrin:
001 #include <iostream>
002 #include "windows.h"
003 #include <wincrypt.h>
... because it's C++ code.
i was refering to
1) i thought the windows.h file always went first
2) each of the 3 includes uses a slightly different syntax :P
C, C+, C++, C- has nothing to do with it
Hi
I know is a old post but i try to translate it to Asm
But i have here my problems can any translate it please?
020 typedef struct _my_blob{
021 BLOBHEADER header;
..
my_blob * kb = NULL;
070 DWORD kbSize = sizeof(my_blob) + strlen(password);
071
072 kb = (my_blob*)malloc(kbSize);
073 kb->header.bType = PLAINTEXTKEYBLOB;
074 kb->header.bVersion = CUR_BLOB_VERSION;
075 kb->header.reserved = 0;
076 kb->header.aiKeyAlg = CALG_RC2;
077 memcpy(&kb->key, password, strlen(password));
078 kb->len = strlen(password);
079
Here is the c code written for c++ 10 express
// dos.cpp : définit le point d'entrée pour l'application console.
//
#include "stdafx.h"
#include "windows.h"
#include <iostream>
#include <wincrypt.h>
using std::cout;
using std::endl;
using std::cin;
#ifndef CALG_HMAC
#define CALG_HMAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HMAC)
#endif
#ifndef CRYPT_IPSEC_HMAC_KEY
#define CRYPT_IPSEC_HMAC_KEY 0x00000100
#endif
#pragma comment(lib, "crypt32.lib")
char * HMAC(char * str, char * password, DWORD AlgId);
typedef struct _my_blob{
BLOBHEADER header;
DWORD len;
BYTE key[0];
}my_blob;
int _tmain(int argc, _TCHAR* argv[])
{
char * hash_sha1 = HMAC("ROSDEVIL", "password", CALG_SHA1);
char * hash_md5 = HMAC("ROSDEVIL", "password", CALG_MD5);
cout <<"Hash HMAC-SHA1: "<<hash_sha1<<" ( "<<strlen(hash_sha1)<<" )"<<endl;
cout <<"Hash HMAC-MD5: "<<hash_md5<<" ( "<<strlen(hash_md5)<<" )"<<endl;
cin.get();
return 0;
}
char * HMAC(char * str, char * password, DWORD AlgId = CALG_MD5){
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HCRYPTKEY hKey = 0;
HCRYPTHASH hHmacHash = 0;
BYTE * pbHash = 0;
DWORD dwDataLen = 0;
HMAC_INFO HmacInfo;
int err = 0;
ZeroMemory(&HmacInfo, sizeof(HmacInfo));
if (AlgId == CALG_MD5){
HmacInfo.HashAlgid = CALG_MD5;
pbHash = new BYTE[16];
dwDataLen = 16;
}else if(AlgId == CALG_SHA1){
HmacInfo.HashAlgid = CALG_SHA1;
pbHash = new BYTE[20];
dwDataLen = 20;
}else{
return 0;
}
ZeroMemory(pbHash, sizeof(dwDataLen));
char * res = new char[dwDataLen * 2];
my_blob * kb = NULL;
DWORD kbSize = sizeof(my_blob) + strlen(password);
kb = (my_blob*)malloc(kbSize);
kb->header.bType = PLAINTEXTKEYBLOB;
kb->header.bVersion = CUR_BLOB_VERSION;
kb->header.reserved = 0;
kb->header.aiKeyAlg = CALG_RC2;
memcpy(&kb->key, password, strlen(password));
kb->len = strlen(password);
if (!CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL,CRYPT_VERIFYCONTEXT | CRYPT_NEWKEYSET)){
err = 1;
goto Exit;
}
if (!CryptImportKey(hProv, (BYTE*)kb, kbSize, 0, CRYPT_IPSEC_HMAC_KEY, &hKey)){
err = 1;
goto Exit;
}
if (!CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHmacHash)){
err = 1;
goto Exit;
}
if (!CryptSetHashParam(hHmacHash, HP_HMAC_INFO, (BYTE*)&HmacInfo, 0)){
err = 1;
goto Exit;
}
if (!CryptHashData(hHmacHash, (BYTE*)str, strlen(str), 0)){
err = 1;
goto Exit;
}
if (!CryptGetHashParam(hHmacHash, HP_HASHVAL, pbHash, &dwDataLen, 0)){
err = 1;
goto Exit;
}
ZeroMemory(res, dwDataLen * 2);
char * temp;
temp = new char[3];
ZeroMemory(temp, 3);
for (unsigned int m = 0; m < dwDataLen; m++){
sprintf(temp, "%2x", pbHash[m]);
if (temp [1] == ' ') temp [1] = '0'; // note these two: they are two CORRECTIONS to the conversion in HEX, sometimes the Zeros are
if (temp [0] == ' ') temp [0] = '0'; // printed with a space, so we replace spaces with zeros; (this error occurs mainly in HMAC-SHA1)
sprintf(res,"%s%s", res,temp);
}
delete [] temp;
Exit:
free(kb);
if(hHmacHash)
CryptDestroyHash(hHmacHash);
if(hKey)
CryptDestroyKey(hKey);
if(hHash)
CryptDestroyHash(hHash);
if(hProv)
CryptReleaseContext(hProv, 0);
if (err == 1){
delete [] res;
return "";
}
return res;
}
//Note: using HMAC-MD5 you could perform the famous CRAM-MD5 used to authenticate
//smtp servers.
The translate in asm (by cl) with the execute are in the attached zip
Best way is perhaps just rewrite it in masm with api call
Yes i try it with api call
here is my stumpy code :biggrin:
But is a first translate it work not i hope any can help me
my goal is use HmacMd5
The correct Hash is:bb41862dea18eaa6f1f426444a1382e6 or??
HMAC PROTO :DWORD,:DWORD,:DWORD
HCRYPTPROV TYPEDEF DWORD
HCRYPTKEY TYPEDEF DWORD
HCRYPTHASH TYPEDEF DWORD
; structure for use with CryptSetHashParam with CALG_HMAC
HMAC_INFO STRUCT ;DEFALIGNMASM
HashAlgid DWORD ?
pbInnerString DWORD ?
cbInnerString DWORD ?
pbOuterString DWORD ?
cbOuterString DWORD ?
HMAC_INFO ENDS
BLOBHEADER STRUCT ;DEFALIGNMASM
bType BYTE ?
bVersion BYTE ?
reserved WORD ?
aiKeyAlg DWORD ?
BLOBHEADER ENDS
;typedef struct _my_blob{
; BLOBHEADER header;
; DWORD len;
; BYTE key[0];
; }my_blob;
_my_blob STRUCT
header BLOBHEADER <>
len DWORD ?
key dword ?;byte ?
_my_blob ends
.const
IDD_DIALOG equ 1000
MS_ENHANCED_PROV equ <"Microsoft Enhanced Cryptographic Provider v1.0">
ALG_TYPE_BLOCK equ < 3 SHL 9>
ALG_CLASS_DATA_ENCRYPT equ < 3 SHL 13>
ALG_CLASS_HASH equ 00008000h ;(4 << 13)1000000000000000
CALG_MD5 equ ALG_CLASS_HASH OR ALG_TYPE_ANY OR ALG_SID_MD5
CALG_RC4 equ ALG_CLASS_DATA_ENCRYPT OR ALG_TYPE_STREAM OR ALG_SID_RC4
CALG_RC2 equ < ALG_CLASS_DATA_ENCRYPT OR ALG_TYPE_BLOCK OR ALG_SID_RC2>
;#########################################################################
.data
.data?
hInstance dd ?
HmacInfo HMAC_INFO <>
kb _my_blob <>
;HMAC("ROSDEVIL", "password", CALG_MD5);
invoke HMAC,chr$ ("ROSDEVIL"),chr$ ("password"),CALG_MD5
HMAC Proc pString:DWORD,pPassWord:DWORD,CALG_ID:DWORD
LOCAL hProv:HCRYPTPROV ;handle to the crypto provider
LOCAL hHash:HCRYPTHASH
LOCAL hKey:HCRYPTKEY
LOCAL hHmacHash:HCRYPTHASH
LOCAL pbHash [16]:BYTE
LOCAL dwDataLen:DWORD
LOCAL kbSize:DWORD
invoke RtlZeroMemory,addr HmacInfo, sizeof HmacInfo
mov HmacInfo.HashAlgid,CALG_MD5
mov dwDataLen,16
invoke RtlZeroMemory,addr pbHash, sizeof dwDataLen
; kb->len = strlen(password);
mov kbSize,sizeof _my_blob +9
mov kb.header.bType,PLAINTEXTKEYBLOB
mov kb.header.bVersion, CUR_BLOB_VERSION
mov kb.header.reserved,0
mov kb.header.aiKeyAlg,CALG_RC2
mov eax,pPassWord
mov kb.key,eax
invoke lstrlen,pString
mov kb.len,eax
invoke CryptAcquireContext,addr hProv, NULL, 0, PROV_RSA_FULL,CRYPT_VERIFYCONTEXT + CRYPT_NEWKEYSET
invoke CryptImportKey,hProv, pPassWord, kbSize, 0, CRYPT_IPSEC_HMAC_KEY, addr hKey
invoke CryptCreateHash,hProv, CALG_HMAC, hKey, 0, addr hHmacHash
invoke CryptSetHashParam,hHmacHash, HP_HMAC_INFO, addr HmacInfo, 0
invoke lstrlen,pString
invoke CryptHashData,hHmacHash, pString, eax, 0
invoke CryptGetHashParam,hHmacHash, HP_HASHVAL,addr pbHash,addr dwDataLen, 0
ret
HMAC endp
Here a verified soluce in asm
HMAC PROTO :DWORD,:DWORD,:DWORD
HCRYPTPROV TYPEDEF DWORD
HCRYPTKEY TYPEDEF DWORD
HCRYPTHASH TYPEDEF DWORD
; structure for use with CryptSetHashParam with CALG_HMAC
my_blob STRUCT
header BLOBHEADER <>
len DWORD ?
key BYTE ?
my_blob ends
.const
RET_ON_FALSE MACRO
.if eax == FALSE
ret
.ENDIF
ENDM
IDD_DIALOG equ 1000
MS_ENHANCED_PROV equ <"Microsoft Enhanced Cryptographic Provider v1.0">
ALG_TYPE_BLOCK equ < 3 SHL 9>
ALG_CLASS_DATA_ENCRYPT equ < 3 SHL 13>
ALG_CLASS_HASH equ 00008000h ;(4 << 13)1000000000000000
CALG_MD5 equ ALG_CLASS_HASH OR ALG_TYPE_ANY OR ALG_SID_MD5
CALG_RC4 equ ALG_CLASS_DATA_ENCRYPT OR ALG_TYPE_STREAM OR ALG_SID_RC4
CALG_RC2 equ < ALG_CLASS_DATA_ENCRYPT OR ALG_TYPE_BLOCK OR ALG_SID_RC2>
;#########################################################################
.data
HmacInfo HMAC_INFO <>
;kb my_blob <>
;HMAC("ROSDEVIL", "password", CALG_MD5);
.code
HMAC Proc uses ebx pString:DWORD,pPassWord:DWORD,AlgId:DWORD
LOCAL hProv:HCRYPTPROV ;handle to the crypto provider
LOCAL hHash:HCRYPTHASH
LOCAL hKey:HCRYPTKEY
LOCAL hHmacHash:HCRYPTHASH
LOCAL pbHash:DWORD
LOCAL dwDataLen:DWORD
Local EncryptedBuffer[50h]:BYTE
LOCAL kbSize:DWORD
ZEROLOCALES kbSize
.if AlgId == CALG_MD5
mov HmacInfo.HashAlgid,CALG_MD5
mov dwDataLen,sizeof EncryptedBuffer ;> 16
lea edx,EncryptedBuffer
mov pbHash,edx
.elseif AlgId == CALG_SHA1
mov HmacInfo.HashAlgid,CALG_SHA1
mov dwDataLen,sizeof EncryptedBuffer ;> 20
lea edx,EncryptedBuffer
mov pbHash,edx
.else
mov eax,0
ret
.endif
;---------------------
mov kbSize,sizeof my_blob +9
invoke malloc,kbSize
mov ebx,eax
mov kb,eax
.LISTALL
mov [ebx].my_blob.header.bType,PLAINTEXTKEYBLOB
mov [ebx].my_blob.header.bVersion, CUR_BLOB_VERSION
.NOLIST
mov [ebx].my_blob.header.reserved,0
mov [ebx].my_blob.header.aiKeyAlg,CALG_RC2
lea edx,[ebx].my_blob.key
invoke lstrcpy,edx,pPassWord ;password is zero terminated,don't take care of lenght
invoke lstrlen,pPassWord
mov [ebx].my_blob.len,eax
invoke CryptAcquireContext,addr hProv, NULL, 0, PROV_RSA_FULL,CRYPT_VERIFYCONTEXT + CRYPT_NEWKEYSET
RET_ON_FALSE
invoke CryptImportKey,hProv,ebx, kbSize, 0, CRYPT_IPSEC_HMAC_KEY, addr hKey
RET_ON_FALSE
invoke CryptCreateHash,hProv, CALG_HMAC, hKey, 0, addr hHmacHash
RET_ON_FALSE
invoke CryptSetHashParam,hHmacHash, HP_HMAC_INFO, addr HmacInfo, 0
RET_ON_FALSE
invoke lstrlen,pString
invoke CryptHashData,hHmacHash, pString, eax, 0
RET_ON_FALSE
invoke CryptGetHashParam,hHmacHash, HP_HASHVAL,pbHash,addr dwDataLen, 0
RET_ON_FALSE
mov edx,pbHash
mov ecx,dwDataLen
ret
HMAC endp
Thanks it works with MD5/SHA1
But i have try to use 3Des without good results
Is 3Des different?
Regards,
If it failed with various values,you need to know the use of the constants.
Here there is four constants:
CALG_SHA1,CALG_RC2,CALG_HMAC,HP_HMAC_INFO
Quote
invoke CryptSetHashParam,hHmacHash, HP_HMAC_INFO, addr HmacInfo, 0
CryptSetHashParam failed with the CALG_3DES perhaps the function need a HP_HASHVAL
Quote
HP_HMAC_INFO. A pointer to an HMAC_INFO structure that specifies the cryptographic hash algorithm and the inner and outer strings to be used.
HP_HASHVAL. A byte array that contains a hash value to place directly into the hash object. Before setting this value, the size of the hash value must be determined by using the CryptGetHashParam function to read the HP_HASHSIZE value.
Some cryptographic service providers (CSPs) do not support this capability
search in the internet seems a good soluce to find the good use for parameters.
Hi
Here is a Hmac-Md5 algo i write this algo with the Rfc2104
This works without CSP (crypto apis)
key:Jefe
len:4
string:what do ya want for nothing?
len:28
HMAC-MD5:750c783e6ab0b503eaa86e310a5db738
Greets,