Jump to content
Danyfirex

Hash HMAC

Recommended Posts

Danyfirex

Hello guys. Here is a small function to create a hash hmac  similar to hash_hmac PHP function.  

Supported are: SHA512,SHA256,SHA1,SHA384,MD5 and RIPEMD160.

 

Local $sSecret = "SecretKey"
Local $sMessage = "AutoIt Rocks!!!"


ConsoleWrite("HMAC-SHA256: " & @TAB & @TAB & _HashHMAC("SHA512", $sMessage, $sSecret) & @CRLF)
ConsoleWrite("HMAC-SHA256: " & @TAB & @TAB & _HashHMAC("SHA256", $sMessage, $sSecret) & @CRLF)
ConsoleWrite("HMAC-SHA1: " & @TAB & @TAB & _HashHMAC("SHA1", $sMessage, $sSecret) & @CRLF)
ConsoleWrite("HMAC-SHA384: " & @TAB & @TAB & _HashHMAC("SHA384", $sMessage, $sSecret) & @CRLF)
ConsoleWrite("HMAC-MD5: " & @TAB & @TAB & _HashHMAC("MD5", $sMessage, $sSecret) & @CRLF)
ConsoleWrite("HMAC-RIPEMD160: " & @TAB &  _HashHMAC("RIPEMD160", $sMessage, $sSecret) & @CRLF)

Func _HashHMAC($sAlgorithm, $bData, $bKey, $bRaw_Output = False)
    Local $oHashHMACErrorHandler = ObjEvent("AutoIt.Error", "_HashHMACErrorHandler")
    Local $oHMAC = ObjCreate("System.Security.Cryptography.HMAC" & $sAlgorithm)
    If @error Then SetError(1, 0, "")
    $oHMAC.key = Binary($bKey)
    Local $bHash = $oHMAC.ComputeHash_2(Binary($bData))
    Return SetError(0, 0, $bRaw_Output ? $bHash : StringLower(StringMid($bHash, 3)))
EndFunc   ;==>_HashHMAC


Func _HashHMACErrorHandler($oError)
    ;Dummy Error Handler
EndFunc   ;==>_HashHMACErrorHandler

It requires .NET Framework  2.0 or higher.

Saludos

Edited by Danyfirex
  • Like 2

Share this post


Link to post
Share on other sites
argumentum

I asked myself ( google really ),  what's the difference and/or use of this vs. a regular hash.

from https://crypto.stackexchange.com/questions/6493/what-is-the-difference-between-a-hmac-and-a-hash-of-data

---------------------------

TL;DR, an HMAC is a keyed hash of data.

A good cryptographic hash function provides one important property: collision resistance. It should be impractical to find two messages that result in the same digest.

An HMAC also provides collision resistance. But it also provides unforgeability. In order to generate an HMAC, one requires a key. If you only share this key with trusted parties, given an HMAC signature, you can be confident that only one of the trusted parties could have generated that signature.

Due to common properties of hash functions, an HMAC is not as simple as hashing the data appended to the key. This construct is vulnerable to length-extension attacks where an attacker can take a message and its HMAC signature, and use this to construct a longer message with a valid signature (thus breaking the guarantee of unforgeability).

---------------------------

Put simply, if you're using a simple hash of a file to guarantee file-integrity, then an attacker could modify the file, re-calculate the hash of the modified file, and replace the old hash with the modified one. With a HMAC, a key is used when calculating the hash value, so unless the attacker has the key, they're unable to calculate a valid hash value of the modified data.

So now I know.

Thanks for sharing :)

PS: so, what would be the function to hash files @Danyfirex ?

Edited by argumentum
add a question

Share this post


Link to post
Share on other sites
Danyfirex

Hello. I really dont know too much about  hashing files. I usally use this for Web API. I think you're talking about something like this.

I'll check deeply later.

 

Saludos

Share this post


Link to post
Share on other sites
argumentum

no need to look too deep for my question. In any case, a salted hash, of the file's hash as string, would do just fine for the purpose. 
I have no need for this implementation. I was just curious about it. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • AlwaysLearning
      By AlwaysLearning
      Hello,
      I have been struggling with this for nearly 20 hours, and I just cannot seem to figure out the formatting for the header request.
      To test this, you will need to use this api key I set up for your testing purposes. (note, I sent tracexx a direct message about this as I didn't realize I could limit API restrictions until just now, so I am now hoping on of you may have the answer on hand)
      I need to be able to GET balance and POST orders.
      Right now, I can't get past the 401/403 errors on my own.
      I believe the Content is formatted for JSON, but using the JSON format didn't work for me ( although that may be because I'm an idiot and formatted something wrong).
      I want to get:
      GET balance page POST delete order page Here is a temporary API key + Secret API key with only the "View Balance Page" and "Delete Order" functions enabled:
      Access-key: tq6GeUrEvfxyF-LG
      Secret Access-Key: cZlz75K1wb8-Ed67pRaXvUWTPW6RTH9q

      Here is the site's API guide (I followed this closely and doubt the error is there): https://coincheck.com/documents/exchange/api#libraries
       
      And here is running source code (needs those keys inputted) which will hash the above keys to the required HMAC SHA256:
      #include <Crypt.au3> #include<WinHttp.au3> Global Const $CALG_SHA_256 = 0x0000800c ;; ===== $api = "/api/accounts/balance" $accessNonCE = _TimeGetStamp() $url = "https://coincheck.com/api/accounts/balance" $body = "" WinHTTP($url, $body) Func WinHTTP($sUrl, $sBody) Local $hOpen = _WinHttpOpen() Local $hConnect = _WinHttpConnect($hOpen, "https://coincheck.com/api/accounts/balance") ; Specify the reguest: ;Local $hRequest = _WinHttpOpenRequest($hConnect, Default, $sApi) $accessKey = "" ;; Add the key from above $secretKey = "" ;; Add the secret key from above $message = $accessNonCE & $sUrl $BinarySignature = HMAC($secretKey, $message) $signature = _Base64Encode($BinarySignature) ;Encode signature Local $hRequest = _WinHttpOpenRequest($hConnect, "GET") _WinHttpAddRequestHeaders($hRequest, 'ACCESS-KEY: '&$accessKey) _WinHttpAddRequestHeaders($hRequest, 'ACCESS-NONCE: '&$accessNonCE) _WinHttpAddRequestHeaders($hRequest, 'ACCESS-SIGNATURE: '&$signature) ; Send request _WinHttpSendRequest($hRequest) ; Wait for the response _WinHttpReceiveResponse($hRequest) Local $sHeader = _WinHttpQueryHeaders($hRequest) ; ...get full header Local $sData = _WinHttpReadData($hRequest) ; Clean _WinHttpCloseHandle($hRequest) _WinHttpCloseHandle($hConnect) _WinHttpCloseHandle($hOpen) ; Display retrieved data MsgBox(0, "Data", $sData) EndFunc Func sha256($message) Return _Crypt_HashData($message, $CALG_SHA_256) EndFunc Func HMAC($key, $message, $hash="sha256") Local $blocksize = 64 Local $a_opad[$blocksize], $a_ipad[$blocksize] Local Const $oconst = 0x5C, $iconst = 0x36 Local $opad = Binary(''), $ipad = Binary('') $key = Binary($key) If BinaryLen($key) > $blocksize Then $key = Call($hash, $key) For $i = 1 To BinaryLen($key) $a_ipad[$i-1] = Number(BinaryMid($key, $i, 1)) $a_opad[$i-1] = Number(BinaryMid($key, $i, 1)) Next For $i = 0 To $blocksize - 1 $a_opad[$i] = BitXOR($a_opad[$i], $oconst) $a_ipad[$i] = BitXOR($a_ipad[$i], $iconst) Next For $i = 0 To $blocksize - 1 $ipad &= Binary('0x' & Hex($a_ipad[$i],2)) $opad &= Binary('0x' & Hex($a_opad[$i],2)) Next Return Call($hash, $opad & Call($hash, $ipad & Binary($message))) EndFunc Func _TimeGetStamp() Local $av_Time $av_Time = DllCall('CrtDll.dll', 'long:cdecl', 'time', 'ptr', 0) If @error Then SetError(99) Return False EndIf Return $av_Time[0] EndFunc Func _Base64Encode($input) $input = Binary($input) Local $struct = DllStructCreate("byte[" & BinaryLen($input) & "]") DllStructSetData($struct, 1, $input) Local $strc = DllStructCreate("int") Local $a_Call = DllCall("Crypt32.dll", "int", "CryptBinaryToString", _ "ptr", DllStructGetPtr($struct), _ "int", DllStructGetSize($struct), _ "int", 1, _ "ptr", 0, _ "ptr", DllStructGetPtr($strc)) If @error Or Not $a_Call[0] Then Return SetError(1, 0, "") ; error calculating the length of the buffer needed EndIf Local $a = DllStructCreate("char[" & DllStructGetData($strc, 1) & "]") $a_Call = DllCall("Crypt32.dll", "int", "CryptBinaryToString", _ "ptr", DllStructGetPtr($struct), _ "int", DllStructGetSize($struct), _ "int", 1, _ "ptr", DllStructGetPtr($a), _ "ptr", DllStructGetPtr($strc)) If @error Or Not $a_Call[0] Then Return SetError(2, 0, ""); error encoding EndIf Return DllStructGetData($a, 1) EndFunc ;==>_Base64Encode
       
    • Graeme
      By Graeme
      I was looking for a way to calculate the sha512 value of files downloaded and eventually came across crypt.au3 in my include folder. It looks good but when I looked at the global constants the three values for Sha 2 are commented out. Is there a reason for that or should these be made available?
    • usmiv4o
      By usmiv4o
      #cs ---------------------------------------------------------------------------- AutoIt Version: 3.2.4.3 Author: usmiv4o Script Function: AutoIt script to check if files in directory are changed. It is usefull for security contra-inteligense measures. Function Name: LoadTripwireDB() Description: Loads database (text file tripwire.txt) and compare files in /test folder for changes. compares Hash (MD5) checksums. If they are not the same starts Initial() Function Name: Initial() Description: Checks directory and makes index of files and their MD5 checksums in text file (tripwire.txt) Function Name: Hush() Description: Checks file and returns its MD5 checksum. Requirement(s): Windows XP Return Value(s): On Success - Returns true. Files are the same as before. On Failure - return false. Example: LoadTripwireDB() #ce ---------------------------------------------------------------------------- #include <Crypt.au3> #include <File.au3> #include <Array.au3> $sDir = @ScriptDir & "\Test" $sFilePath = @ScriptDir & "\tripwire.txt" Func Hush(ByRef $sFile) $sRead = FileOpen( $sFile) $dHash = _Crypt_HashData($sRead, $CALG_MD5) ; Create a hash of the text entered. ConsoleWrite("Hash of file " & $sFile & " is " & $dHash & @CRLF) EndFunc ;ConsoleWrite("Files in Dir are " & $aScriptDir[0] & @CRLF) ;$sFilePath = @ScriptDir & "\Examples.txt" ;_FileWriteFromArray($sFilePath, $aScriptDir, 1) ;_ArrayDisplay($aScriptDir, "1D display") Func Initial() $aScriptDir = _FileListToArray($sDir) for $i = 1 To UBound($aScriptDir) - 1 $dHash = _Crypt_HashData($i, $CALG_MD5) ;ConsoleWrite("File " & $aScriptDir[$i] & " is " & $dHash & @CRLF) ConsoleWrite($aScriptDir[$i] & ":" & $dHash & @CRLF) ;Hush($aScriptDir[$i]) ;FileWrite $hFileOpen = FileOpen($sFilePath, $FO_APPEND) If $hFileOpen = -1 Then MsgBox($MB_SYSTEMMODAL, "", "An error occurred when reading the file.") EndIf FileWrite($hFileOpen, $aScriptDir[$i] & ":" & $dHash & @CRLF) Next EndFunc Func Monitor() $aScriptDir = _FileListToArray($sDir) for $i = 1 To UBound($aScriptDir) - 1 Next EndFunc Func LoadTripwireDB() $comparison_ok = false $dArray = _FileListToArray($sDir) ;directory $dArray0 = UBound($dArray) - 1 $fArray = FileReadToArray($sFilePath) ;file $fArray0 = UBound($fArray) ;_ArrayDisplay($dArray, "files array") if $dArray0 = $fArray0 Then ; are file same as recorded in txt file? ;ConsoleWrite("files in monitoring dir: " & $dArray[0] & " = file recorded: " & $fArray0 & @CRLF & $fArray[0]& @CRLF) for $i = 1 To UBound($dArray) - 1 ;ConsoleWrite("i = " & $i & @CRLF) $dHash = _Crypt_HashData($i, $CALG_MD5) ;binary ;$dHash = BinaryToString($dHash) $ffhash = StringSplit( $fArray[$i-1],":") $fhash = $ffhash[2] ;ConsoleWrite("IsBinary $dHash " & IsBinary($dHash) & @CRLF) if $dHash = $fhash Then ;if compared hashes are equal ;ConsoleWrite($fhash & ":" & $dHash & " equal" & @CRLF) ;ConsoleWrite("File: " & $fhash & @CRLF & "Directory: " & $dHash & @CRLF & "equal: yes " & @CRLF) Else ;if compared hashes are not equal ;ConsoleWrite("File: " & $fhash & @CRLF & "Directory: " & $dHash & @CRLF & "equal: not " & @CRLF) ;MsgBox(0,"hash md5",$fhash & ":" & $dHash & " not equal") EndIf Next ;ConsoleWrite("hashes are equal" & @CRLF) $comparison_ok = true Else ConsoleWrite("number of files in monitoring dir are not same as recorded" & @CRLF) ConsoleWrite("directory: " & $dArray[0] &":"& "files: " & UBound($fArray) - 1 & @CRLF) EndIf Return $comparison_ok EndFunc #main if LoadTripwireDB() = true Then ConsoleWrite(" hashes are equal " & @CRLF) ElseIf LoadTripwireDB() <> true Then ConsoleWrite(" hashes are not equal " & @CRLF) ConsoleWrite(" hashes are not equal " & @CRLF) Initial() EndIf  
      tripwire.au3
      tripwire.txt
    • argumentum
      By argumentum
      I've got a bunch of hash from files in a folder
      0x45B265C13EC41DD3272E547A837EF0604E06EF6C 0x73418EE0D435F0995DE000A0CB9A895B8031D62B 0x6FB325DDFA9AFCB148B815F41C94F5BBC3735E0B 0xE8BC5E1676E64E9EE77A7EBD56D910D60D453A2A 0xFF311E2FEC610B2E0A3169435CBC48D5B1B53A57 0x728EDF8577DF247CBC69ED6F2F9EACB3BF845150 0x8CABC5A4BDA856E0D0E884D0F4A335CB2457941D 0xCEBB04B9099141009329E13EDBD8B5CFB14A49A5 0xD7AA968FCF6AC9691F6ED801BA9291EBBBAFED71 0xBBBA76A66C54D53BADE77245D9F205F1EB9CC685 0x39DD14E5DB99F39F68182494C0B48CEFB5DDFDDF 0x32C2A01B523D973D933FC004237CAB4B792231BF 0x6AE1A10B7505DDABEECEAFD13B2EC2A8D7286587 how can I make a sum of the hash to have a hash that'd represent these hash as a single hash resultant of these ?.
      I was thinking of sorting them and adding 'em to a string and hash that string but there may be a proper way to do it.
      Any and all ideas are welcomed.
    • Crash
      By Crash
      Dear AutoIt communities,
      I wish to perform SHA-256 hashing with AutoIt. I noticed Help File shows the use of MD2, MD4, MD5, SHA1. To my knowledge, all of these aren't cryptographically secure anymore and SHA-2 (SHA-256, SHA-384, SHA-512) is the way to hash passwords.
      I poked around Crypt.au3 and found SHA-2 constants are commented out. Why is this? I'm using latest public release, v 3.3.14.2
      ; #CONSTANTS# =================================================================================================================== Global Const $PROV_RSA_FULL = 0x1 Global Const $PROV_RSA_AES = 24 Global Const $CRYPT_VERIFYCONTEXT = 0xF0000000 Global Const $HP_HASHSIZE = 0x0004 Global Const $HP_HASHVAL = 0x0002 Global Const $CRYPT_EXPORTABLE = 0x00000001 Global Const $CRYPT_USERDATA = 1 Global Const $CALG_MD2 = 0x00008001 Global Const $CALG_MD4 = 0x00008002 Global Const $CALG_MD5 = 0x00008003 Global Const $CALG_SHA1 = 0x00008004 ; Global Const $CALG_SHA_256 = 0x0000800c ; Global Const $CALG_SHA_384 = 0x0000800d ; Global Const $CALG_SHA_512 = 0x0000800e Global Const $CALG_3DES = 0x00006603 Global Const $CALG_AES_128 = 0x0000660e Global Const $CALG_AES_192 = 0x0000660f Global Const $CALG_AES_256 = 0x00006610 Global Const $CALG_DES = 0x00006601 Global Const $CALG_RC2 = 0x00006602 Global Const $CALG_RC4 = 0x00006801 Global Const $CALG_USERKEY = 0 Global Const $KP_ALGID = 0x00000007  
      I thought this could be compatibility issues, and older Windows doesn't support SHA-2.
      Without knowing what I am doing, MSDN help appears to say SHA256 is available since Windows Platform 10 (https://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256(v=vs.110).aspx) However other sources said SHA-2 has been supported since Win XP SP 3.
      What is happening? How can I implement SHA-2 with confidence that it will work on Win XP? Unfortunately I do not have an older computer or virtual PC to test it out. I'm running latest Windows 10 and SHA-256, SHA-384, SHA-512 all works fine. (If you like to try on your machine, I've attached the help file hashing example with SHA-2 algo added)
       
      Thank you yet again
      Crash
      sdfsdaf.au3
×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.