contra Posted August 10, 2017 Share Posted August 10, 2017 Hello, I want to include the kraken.com API (https://www.kraken.com/help/api) in an autoit script. After few days of thinking and coding, I end up with a problem I cannot solve. I can simulate physical models with MATLAB, but autoit is just a hobby and that's why I need your help. The API has the following requirement for the headers: API-Key = API key API-Sign = Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key POST data: nonce = always increasing unsigned 64 bit integer My problem is now that the API-Sign is not correct. First, I had a problem with the _Base64Encode() function, because of line breaks after 76 chars but now it works and the headers are sent, but I receive an error message that the sign is not correct. I searched for similar problems and found out that the output of the SHA256 hash should be BINARY and the small uri path should be also BINARY and then the bytes have to be concatenate. After applying the hmac_sha512 algorithm it should be BINARY as well and then be encoded to base64. The included Binary() function in autoit doesnt work well and I don't know what to do now. I hope someone can help me, this would be very nice! I give away some ETH if someone found a solution, maybe 0.1 The original Library provided by kraken is written in PHP (see link at the beginning, scroll down a bit), maybe this is helpful. Let me know if there are any questions. Here I found the solution to use BINARY (you can see this in the PHP code as well I think): https://superuser.com/questions/1123526/curl-example-for-accessing-authenticated-kraken-api This is my code: expandcollapse popup#include <Crypt.au3> #include <Date.au3> #include <Array.au3> #Include <Base64.au3> #Include <Memory.au3> #Include <SHA224_256.au3> #include <String.au3> Local $apikey = "a8/dt1+Sjw6a8/OspaeKgTvQXjVGDa7MTwtkE8U85oJpX+OThqMjLcSf";you can use this for testing, it uses a test account Local $apisecret = "gmJASh6IR57seYYJE5z6qEU5sT7OBm+QPzDBp8/89OnaTNydM7rbsKo0hHbHAfMEW1zcPrN6EPDc0PD2hMEWyQ==";you can use this for testing, it uses a test account ;I hardcoded the request for the Balance to eliminate problems $output=KRAKEN_api($apikey,$apisecret) msgbox(0,"Balance JSON",$output) Func KRAKEN_api($key,$secret) Local $nonce= @Year&@MON&@MDAY&@HOUR&@MIN&@SEC&@MSEC Local $params = "nonce=" & $nonce Local $path="/0/private/Balance" Local $sign = hmac($path&_SHA256($nonce&$params), _Base64Decode($secret)); calculating SHA256 of nonce + POST data (POST data is only the nonce in my case) and then calculating hmac $oHTTP = ObjCreate("winhttp.winhttprequest.5.1") $oHTTP.Open("POST", "https://api.kraken.com/0/private/Balance", false) $oHTTP.SetRequestHeader("API-Key", $key) $oHTTP.SetRequestHeader("API-Sign", _Base64Encode($sign)) $oHTTP.Send($params) $oReceived = $oHTTP.ResponseText $oStatusCode = $oHTTP.Status RETURN $oReceived EndFunc Func hmac($message, $key, $hash = "SHA512") Local $blocksize = 128 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 ;==>hmac Func SHA512($message) Return _Crypt_HashData($message, 0x0000800e) EndFunc ;==>SHA512 And these are the helper functions: base64.au3 expandcollapse popup#include-once ;=============================================================================== ; ; Build lookup tables as global constants ; ;=============================================================================== #Region Build look-up tables ;The Base64 alphabet, in an array which can be used as a 6-bit lookup table Global Const $gcac_Base64Alphabet[64] = [ _ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', _ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', _ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', _ 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'] ;reverse look-up table to convert an ascii value to a 6-bit value Global Const $gcai_Base64Reverse[256] = [ _ - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, _ - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, _ - 1, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, _ - 1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, _ - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, _ - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, _ - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, _ - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] ;A 12-bit to 16-bit lookup table for encoding to base64 Global Const $gcas_Base64Table12 = _Base64Table12() ;a 14-bit to 12-bit reverse lookup (basically a truncated 16-bit to 12-bit table, uses 7+7 instead of 8+8) Global Const $gcai_Base64Table14 = _Base64Table14() ;Build a 12-bit to 16-bit lookup table Func _Base64Table12() Dim $a_Out[4096], $i_Count1, $i_Count2 ;ProgressOn(@ScriptName, 'Base64 Lookup Tables','Building Encoder Table...',-1,-1,16) For $i_Count1 = 0 To 63 For $i_Count2 = 0 To 63 $a_Out[$i_Count1 * 64 + $i_Count2] = $gcac_Base64Alphabet[$i_Count1] & $gcac_Base64Alphabet[$i_Count2] Next ;ProgressSet(100 * $i_Count1 / 63) Next ;ProgressOff() Return $a_Out EndFunc ;==>_Base64Table12 ;a 14-bit to 12-bit reverse lookup (basically a truncated "16-bit to 12-bit" table, uses 7+7 instead of 8+8) ;note: 12-bit values have been shifted to easier fit into the Big Edian style of the BinaryString() function ;The table has 2 columns. The columns represent the 4-bit groups as 00C0AB and EF0D00 respectively Func _Base64Table14() Dim $a_Out[16384][2], $i_Count1, $i_Count2, $i_Temp1, $i_Temp2 ;ProgressOn(@ScriptName, 'Base64 Lookup Tables','Building Decoder Table...',-1,-1,16) For $i_Count1 = 0 To 63 For $i_Count2 = 0 To 63 $i_Temp1 = Asc($gcac_Base64Alphabet[$i_Count1]) * 128 + Asc($gcac_Base64Alphabet[$i_Count2]) $i_Temp2 = $i_Count1 * 64 + $i_Count2 $a_Out[$i_Temp1][0] = BitShift($i_Temp2, 4) + BitAND($i_Temp2, 15) * 4096 $a_Out[$i_Temp1][1] = BitAND($i_Temp2, 255) * 65536 + BitAND($i_Temp2, 3840) Next ;ProgressSet(100 * $i_Count1 / 63) Next ;ProgressOff() Return $a_Out EndFunc ;==>_Base64Table14 #endregion ;=============================================================================== ; ; Description: Convert String to Base64 ; Syntax: _Base64Encode($s_Input, $b_WordWrap, $s_ProgressTitle) ; Parameter(s): ; $s_Input - String to convert to a Base64 String ; $b_WordWrap - Add a @CRLF to the output every 76 Char. Default = True ; $s_ProgressTitle - Show a Progress Bar, This is the title of the progress bar. Default = "" = No progress bar. ; ; Requirement(s): v3.2.4.0 ; ; Return Value: A Base64 encoded version of that string ; ; Authors: Original functions - blindwig ; Edit for UDF and Clean/Speedup Code - Mikeytown2 ; Code Speedup/Standards - blindwig ; Note(s): ; To encode a binary file, adapt this codeblock to your program ; $file = "binaryfile.dat" ; _Base64Encode (BinaryToString(FileRead(FileOpen($file, 16), FileGetSize($file)))) ; ; Autoit will most likely crash if input is large (24+ MB) ; ;=============================================================================== Func _Base64Encode($s_Input, $b_WordWrap = '', $s_ProgressTitle = '') Local $i_Count, $i_Count2, $s_Out = '', $i_Temp ;Initialize ProgressBar ;Break the input up into bytes Local $as_Input = StringSplit($s_Input, "") ;Main Processing Loop - handles 3-byte chunks For $i_Count = 1 To $as_Input[0] - Mod($as_Input[0], 3) Step 3 $i_Temp = Asc($as_Input[$i_Count + 1]) $s_Out &= $gcas_Base64Table12[Asc($as_Input[$i_Count + 0]) * 16 + BitShift($i_Temp, 4) ] _ & $gcas_Base64Table12[BitAND($i_Temp, 15) * 256 + Asc($as_Input[$i_Count + 2]) ] Next ;Handle any left-over bytes (a final chunk less than 3 bytes) Switch Mod($as_Input[0], 3) Case 1 $s_Out &= $gcac_Base64Alphabet[BitShift(Asc($as_Input[$as_Input[0]]), 2) ] _ & $gcac_Base64Alphabet[BitAND(Asc($as_Input[$as_Input[0]]), 3) * 16 ] & '==' Case 2 $s_Out &= $gcac_Base64Alphabet[BitShift(Asc($as_Input[$as_Input[0] - 1]), 2) ] _ & $gcac_Base64Alphabet[BitAND(Asc($as_Input[$as_Input[0] - 1]), 3) * 16 + BitShift(Asc($as_Input[$as_Input[0]]), 4) ] _ & $gcac_Base64Alphabet[BitAND(Asc($as_Input[$as_Input[0]]), 15) * 4 ] & '=' EndSwitch ;DONE! Return $s_Out EndFunc ;==>_Base64Encode ;=============================================================================== ; ; Description: Decodes a given base64 string ; Syntax: _Base64Decode($as_CypherText, $s_ProgressTitle) ; Parameter(s): ; $as_CypherText - Base64 String ; $s_ProgressTitle - (optional) Show a Progress Bar, This is the title of the progress bar. Default ("") ;No progress bar. ; ; Requirement(s): v3.2.4.0 ; ; Return Value(s): On Success - Returns decoded Base64 string ; ; Authors: Original functions - blindwig ; Edit for UDF and Clean/Speedup Code - Mikeytown2 ; Code Speedup/Standards - blindwig ; Note(s): ; will always strip all @CRLF, @CR, @LF characters before processing and any non Base64 characters ; ; Will most likely crash if input is large (32+ MB) ; ;=============================================================================== Func _Base64Decode($s_CypherText, $s_ProgressTitle = '') Local $i_Count = 0, $i_Count2, $s_Out = '', $i_CypMod, $i_Temp If $s_ProgressTitle Then ProgressOn($s_ProgressTitle, 'Base64 Decoding', 'Pre-processing input:', -1, -1, 16) ;first filter EOL characters If $s_ProgressTitle Then ProgressSet(18, 'Pre-processing input: Filtering EOL...') $s_CypherText = StringReplace(StringStripCR($s_CypherText), @LF, "") ;check for non-base64 characters, filter if needed If $s_ProgressTitle Then ProgressSet(25, 'Pre-processing input: Checking for junk...') If StringRegExp($s_CypherText, '[^0-9a-zA-Z/+=]', 0) Then If $s_ProgressTitle Then ProgressSet(50, 'Pre-processing input: Filtering junk...') $s_CypherText = StringRegExpReplace($s_CypherText, '[^0-9a-zA-Z/+=]', '') EndIf ;Break the input up into bytes If $s_ProgressTitle Then ProgressSet(75, 'Pre-processing input: Building array...') $as_CypherText = StringSplit($s_CypherText, "") ;Pad the input to a multiple of four characters If $s_ProgressTitle Then ProgressSet(95, 'Pre-processing input: Padding array...') $i_CypMod = Mod($as_CypherText[0], 4) If $i_CypMod Then ReDim $as_CypherText[$as_CypherText[0] + 5 - $i_CypMod] For $i_Count = $as_CypherText[0] + 1 To UBound($as_CypherText) - 1 $as_CypherText[$i_Count] = '=' Next $as_CypherText[0] = UBound($as_CypherText) - 1 EndIf ;Main decoding loop - process all but the last 4 bytes If $s_ProgressTitle Then ProgressSet(0, 'Main Decode Loop...', 'Base64 Decoding ' & $as_CypherText[0] & ' bytes') For $i_Count2 = 1 To $as_CypherText[0] - Mod($as_CypherText[0], 100) - 4 Step + 100 For $i_Count = $i_Count2 To $i_Count2 + 96 Step + 4 $i_Temp = $gcai_Base64Table14[Asc($as_CypherText[$i_Count + 0]) * 128 + Asc($as_CypherText[$i_Count + 1]) ][0] _ + $gcai_Base64Table14[Asc($as_CypherText[$i_Count + 2]) * 128 + Asc($as_CypherText[$i_Count + 3]) ][1] $s_Out &= StringLeft(BinaryToString($i_Temp), 3) Next ProgressSet(100 * $i_Count / $as_CypherText[0]) Next For $i_Count = $i_Count To $as_CypherText[0] - 4 Step + 4 $i_Temp = $gcai_Base64Table14[Asc($as_CypherText[$i_Count + 0]) * 128 + Asc($as_CypherText[$i_Count + 1]) ][0] _ + $gcai_Base64Table14[Asc($as_CypherText[$i_Count + 2]) * 128 + Asc($as_CypherText[$i_Count + 3]) ][1] $s_Out &= StringLeft(BinaryToString($i_Temp), 3) Next Else For $i_Count = 1 To $as_CypherText[0] - 4 Step + 4 $i_Temp = $gcai_Base64Table14[Asc($as_CypherText[$i_Count + 0]) * 128 + Asc($as_CypherText[$i_Count + 1]) ][0] _ + $gcai_Base64Table14[Asc($as_CypherText[$i_Count + 2]) * 128 + Asc($as_CypherText[$i_Count + 3]) ][1] $s_Out &= StringLeft(BinaryToString($i_Temp), 3) Next EndIf ;last run - left over bytes (4 or less, if any) If $as_CypherText[0] Then ;make sure there is some input (not zero). If $as_CypherText[0] > $i_Count Then Local $ai_Bytes[4] $ai_Bytes[0] = $gcai_Base64Reverse[Asc($as_CypherText[$i_Count + 0]) ] $ai_Bytes[1] = $gcai_Base64Reverse[Asc($as_CypherText[$i_Count + 1]) ] $ai_Bytes[2] = $gcai_Base64Reverse[Asc($as_CypherText[$i_Count + 2]) ] $ai_Bytes[3] = $gcai_Base64Reverse[Asc($as_CypherText[$i_Count + 3]) ] Select Case $ai_Bytes[0] = -1;File ended on a perfect octet Case $ai_Bytes[1] = -1;This should never happen SetError(-1) Case $ai_Bytes[2] = -1;Only the first 2 bytes to be considered $s_Out &= Chr($ai_Bytes[0] * 4 + BitShift($ai_Bytes[1], 4)) Case $ai_Bytes[3] = -1;Only the first 3 bytes to be considered $s_Out &= Chr($ai_Bytes[0] * 4 + BitShift($ai_Bytes[1], 4)) _ & Chr(BitAND($ai_Bytes[1] * 16 + BitShift($ai_Bytes[2], 2), 255)) Case Else;All 4 bytes to be considered $s_Out &= Chr($ai_Bytes[0] * 4 + BitShift($ai_Bytes[1], 4)) _ & Chr(BitAND($ai_Bytes[1] * 16 + BitShift($ai_Bytes[2], 2), 255)) _ & Chr(BitAND($ai_Bytes[2] * 64 + $ai_Bytes[3], 255)) EndSelect EndIf EndIf ;Finish ProgressBar If $s_ProgressTitle Then ProgressOff() ;DONE! Return $s_Out EndFunc ;==>_Base64Decode and SHA224_256.au3 expandcollapse popup; ----------------------------------------------------------------------------- ; SHA224/256 Hash Machine Code UDF ; Purpose: Provide The Machine Code Version of SHA224/256 Hash Algorithm In AutoIt ; Author: Ward ; ----------------------------------------------------------------------------- #Include-once #Include <Memory.au3> Global $_SHA224_256_CodeBuffer, $_SHA224_256_CodeBufferMemory Global $_SHA224_InitOffset, $_SHA224_InputOffset, $_SHA224_ResultOffset Global $_SHA256_InitOffset, $_SHA256_InputOffset, $_SHA256_ResultOffset Global $_HASH_SHA224[4] = [28, 104, '_SHA224_', '_SHA224_256_'] Global $_HASH_SHA256[4] = [32, 104, '_SHA256_', '_SHA224_256_'] Func _SHA224_256_Exit() $_SHA224_256_CodeBuffer = 0 _MemVirtualFree($_SHA224_256_CodeBufferMemory, 0, $MEM_RELEASE) EndFunc Func _SHA224_256_Startup() If Not IsDllStruct($_SHA224_256_CodeBuffer) Then If @AutoItX64 Then Local $Code = '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' $Code &= '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' $Code &= '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' $Code &= '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' $Code &= 'WEh3QMEtKrn0cM8OF/s9phD0ENMSD4hQDxhKMokfGQCDxHhbXl8cXUFctwiO3lnDIuylcgQxKPpIZTATy+loITiMv4DTTP5k3YxyH1BezDGUQWBWsR4UzdP/qRSkJCF/AvmD4D/32XhPg8fXQwEJAB74OEKIDAMPKIbWHoDeuECgR41r7ki6ovwpGMAx0rzf6CjFA1xn6hbZsZfV/8T2wxgBujhRD4V5As8MQO7H+RQGGASB3EBK0THAtYE89sIE6MnzMkirKrItHJhRlROD4kABhIoCo0Ng4xUo1gStNw/IvNU4MmUyIEWF5HQoIUHxZQGUSgaMpQRfSJAlAQNAD8qJFCEAA70EoDnIdXnulHK/S1rGCpML/FRgUgZ/iqJBWMOR1jgUEcvU0N+D6PICGyTpfM6RxgeREHQeZsdqkVGDzAiehGJiJevkiBMVlAS8hYRECBXXwYPqBEEY6RJDQwMDSI17AbI38fD+TUmRPgJ0cenTI+yYy0nB/lSeCsx/UOXHn8ShCihNhcCxA3FgdF/h5j9ClXlhD74ifgXrDUkBANVgSIX/dGRGFN2Bw/Upy6Lrgu77dkFN/fe0xsKKSdgodqPNigFBACkgnhaoy4P+GUB1yCz6ngbhQTD26PHTo+5GCXW6JAco20hP5SRBaNdWjQjOU2QiVxMgSQIKf3Z+ZDSSIih1R48MZkAx7UD5zD7iyOnfRCQzGpyrpqwrGgz4P3fkRENowDrBN152QWfFMlQHD4Mm4wFeYCPfIArDvdFCKcWGsugyZ++Q63kTIbOiPbDxJmAxoy5oC1DpyNRRI5uu7MKLx42Vj8JAbiRnH+YJaqwhPJ6FrpS7rDwU4BkIcvNuYDwRDDr1T0SlEAh/Ug5RgRSMaAWbEBir2TGDH+JRQGJjMAgjHBnNIOBbfFCEbhATkIgYukgphcNTC67RK1sJGRL9BoMwZzAgCP/ofvyqlEOeB0swW+lfyqF2CNieBcFAB9V8NoUCF91wMBA5WSEO9wIxC8D/EBEVIVhoAqeP+WQ2CKRP+r5/kAeE3ft8VpLmZM8G1oCowfzzCqRfXsMQRNAyqmMIAAA=' Else Local $Code = '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' $Code &= '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' $Code &= '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' $Code &= 'ZxAcPDi2/iXjJ/rX2/5ZUGoqUchQkRSIEFFQDT8lKwBPrDcIAsdSjIpZgS48iZFceHyNSDVmm/w3GBQ5iVRskM4q9Qy3izcohPmqDRMNAetP1Vjpw1vbaXRCT3DWzANMtTFXAznvWhPL81xYjrfIUUwSNJOwvLzYskw5MxMsJnM8SGC0Hvr/N76QHyuljSjSlVgqT0sblO2pXN5hpXHJlB62EgHZEzyWc0eqF+g8Md2qDCq4cCCsb9OTvamKEhCUZejX1tS2/GVDrifrZrOCrgX4/algjVSj4/L71g7pW5aUKB9qN58ArDvrbFCkVoujdiWJzwIwIcuGCwHm8Sg6mijmOCn3AY6k5Uny+7OWJQGIwzHXc5gWIfPIKRScLBDTMx9ZDHTVnCxJcBiWLET781lBouSNvAYd96P5vjimN+lvJKGgn8tTEfRLglkKoglYAfowny8/lxKu+TFFm1I3Bl+dMxDVlUEWAdiItouZX6SeFt2Nugy+IUj3QU9lvihFGJZPa1BEnrxF3UUM6wNJCQwAICvyeHFExjSaVU1EPC0MRGOCqCiuI75Sq4wcQwzPCVjSxuUIlghFxUmPDJF6BjWmScV13hSQESuJMvuhEGqKwoCRshwkyAKpMfstk2wnIBam4EtgUl8yn12EspzuNhAsFXgBO8dypNf0F/h14ZMbYDcd9x7nV21D83Y3lUtl+0WETnDyARoLgcSEgH1bXl9dw1UoV79KWFa2KFOZJIPsiANAYNP/QG/m+Uz3iwPRg+A/CcuIeO49wAGD+DgPhrEYWbpACynCPI17Slj3tAjH3q53Jwncz4x1AxH69Ni+w7w/37wouP+D9sMBujgMPw+Fwg33KscCDESmiQDRMcDB6QL2wubzZKskgUWD4gHEd4t7ZDrDo9K4c2APB6T3A8HmO4ZxEabx9cnR0NHIScvwQzjAxUs86MnXwb6F7XQWPdlsljaD7TuBxRSGUq45h4rw4sQsm+RG/LFCruQgjI1DQJfKIoNqxgeHUYRmx9qthjATiQ/rc3K8KevoExDqYyzpSlglWmBoewGyN/oxyRtVBbpXgh1WRj0ATIXJi1BgdHk4jUDmfj+rWDx5hesirfxZGycwLHL9NISRNQABSGARWGQEhf90R76MU9YSOf52HfwoL/j3mhZaBBJLhsN3eghS0K871O1zJfjygwz6QHWoFzygLejCUdaJQTDrl0LxTE7VgpGTzDNySEFAdtn+/lJ/5lHCO9lI66FCYCTddU5E4oc9/5LFQENS6in4y+/J6HOtnw9Ef0c/d+qARsCJwqPOrlmY9WQT6i5YYQFyoLt6ZJFhQr9AIInaKcem6h75AfuH/ujjOSQ8ovtmMCrKbATCRBJG67xx+vHQYDwa6btRBqwgr7DJGEJAxwZn5jMJag5gcKX99ASFGK5nuw4IchDzbjwCDDr1T6UAEH9SDkBRFAiMaAWbARir2YMfABwZzTLgW3BkEwPAIMNTMckmrhhGklz8I51k90QIZAPq6AX9euzYNVQYWyvrgIBg2J4FwYcCB9V8NiAX3XAwiDlZIg73CDELwP+CERVYaCCnj/lkiKRPI/q++QcLEYX8oVZXKRNMt5LlCiFG5C/8KIP59GYn2AFl/AIspEk2z0EFZqWDYTB4kmcK86sPPofhA3Ok63QWDF9ew1d3EIgwD2K21AxpwwJmA60IdEIDCgqqSQpCdfalP/yEciBAql/DwAA=' EndIf Local $Opcode = String(_SHA224_256_CodeDecompress($Code)) $_SHA224_InitOffset = (StringInStr($Opcode, "89DB") - 3) / 2 $_SHA224_InputOffset = (StringInStr($Opcode, "87DB") - 3) / 2 $_SHA224_ResultOffset = (StringInStr($Opcode, "09DB") - 3) / 2 $_SHA256_InitOffset = (StringInStr($Opcode, "89C9") - 3) / 2 $_SHA256_InputOffset = (StringInStr($Opcode, "87C9") - 3) / 2 $_SHA256_ResultOffset = (StringInStr($Opcode, "09C9") - 3) / 2 $Opcode = Binary($Opcode) $_SHA224_256_CodeBufferMemory = _MemVirtualAlloc(0, BinaryLen($Opcode), $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) $_SHA224_256_CodeBuffer = DllStructCreate("byte[" & BinaryLen($Opcode) & "]", $_SHA224_256_CodeBufferMemory) DllStructSetData($_SHA224_256_CodeBuffer, 1, $Opcode) OnAutoItExitRegister("_SHA224_256_Exit") EndIf EndFunc Func _SHA224Init() If Not IsDllStruct($_SHA224_256_CodeBuffer) Then _SHA224_256_Startup() Local $Context = DllStructCreate("byte[" & $_HASH_SHA224[1] & "]") DllCall("user32.dll", "none", "CallWindowProc", "ptr", DllStructGetPtr($_SHA224_256_CodeBuffer) + $_SHA224_InitOffset, _ "ptr", DllStructGetPtr($Context), _ "int", 0, _ "int", 0, _ "int", 0) Return $Context EndFunc Func _SHA256Init() If Not IsDllStruct($_SHA224_256_CodeBuffer) Then _SHA224_256_Startup() Local $Context = DllStructCreate("byte[" & $_HASH_SHA256[1] & "]") DllCall("user32.dll", "none", "CallWindowProc", "ptr", DllStructGetPtr($_SHA224_256_CodeBuffer) + $_SHA256_InitOffset, _ "ptr", DllStructGetPtr($Context), _ "int", 0, _ "int", 0, _ "int", 0) Return $Context EndFunc Func _SHA224Input(ByRef $Context, $Data) If Not IsDllStruct($_SHA224_256_CodeBuffer) Then _SHA224_256_Startup() If Not IsDllStruct($Context) Then Return SetError(1, 0, 0) $Data = Binary($Data) Local $InputLen = BinaryLen($Data) Local $Input = DllStructCreate("byte[" & $InputLen & "]") DllStructSetData($Input, 1, $Data) DllCall("user32.dll", "none", "CallWindowProc", "ptr", DllStructGetPtr($_SHA224_256_CodeBuffer) + $_SHA224_InputOffset, _ "ptr", DllStructGetPtr($Context), _ "ptr", DllStructGetPtr($Input), _ "uint", $InputLen, _ "int", 0) EndFunc Func _SHA256Input(ByRef $Context, $Data) If Not IsDllStruct($_SHA224_256_CodeBuffer) Then _SHA224_256_Startup() If Not IsDllStruct($Context) Then Return SetError(1, 0, 0) $Data = Binary($Data) Local $InputLen = BinaryLen($Data) Local $Input = DllStructCreate("byte[" & $InputLen & "]") DllStructSetData($Input, 1, $Data) DllCall("user32.dll", "none", "CallWindowProc", "ptr", DllStructGetPtr($_SHA224_256_CodeBuffer) + $_SHA256_InputOffset, _ "ptr", DllStructGetPtr($Context), _ "ptr", DllStructGetPtr($Input), _ "uint", $InputLen, _ "int", 0) EndFunc Func _SHA224Result(ByRef $Context) If Not IsDllStruct($_SHA224_256_CodeBuffer) Then _SHA224_256_Startup() If Not IsDllStruct($Context) Then Return SetError(1, 0, "") Local $Digest = DllStructCreate("byte[" & $_HASH_SHA224[0] & "]") DllCall("user32.dll", "none", "CallWindowProc", "ptr", DllStructGetPtr($_SHA224_256_CodeBuffer) + $_SHA224_ResultOffset, _ "ptr", DllStructGetPtr($Context), _ "ptr", DllStructGetPtr($Digest), _ "int", 0, _ "int", 0) Return DllStructGetData($Digest, 1) EndFunc Func _SHA256Result(ByRef $Context) If Not IsDllStruct($_SHA224_256_CodeBuffer) Then _SHA224_256_Startup() If Not IsDllStruct($Context) Then Return SetError(1, 0, "") Local $Digest = DllStructCreate("byte[" & $_HASH_SHA256[0] & "]") DllCall("user32.dll", "none", "CallWindowProc", "ptr", DllStructGetPtr($_SHA224_256_CodeBuffer) + $_SHA256_ResultOffset, _ "ptr", DllStructGetPtr($Context), _ "ptr", DllStructGetPtr($Digest), _ "int", 0, _ "int", 0) Return DllStructGetData($Digest, 1) EndFunc Func _SHA224($Data) Local $Context = _SHA224Init() _SHA224Input($Context, $Data) Return _SHA224Result($Context) EndFunc Func _SHA256($Data) Local $Context = _SHA256Init() _SHA256Input($Context, $Data) Return _SHA256Result($Context) EndFunc Func _SHA224_256_CodeDecompress($Code) If @AutoItX64 Then Local $Opcode = '0x89C04150535657524889CE4889D7FCB28031DBA4B302E87500000073F631C9E86C000000731D31C0E8630000007324B302FFC1B010E85600000010C073F77544AAEBD3E85600000029D97510E84B000000EB2CACD1E8745711C9EB1D91FFC8C1E008ACE8340000003D007D0000730A80FC05730783F87F7704FFC1FFC141904489C0B301564889FE4829C6F3A45EEB8600D275078A1648FFC610D2C331C9FFC1E8EBFFFFFF11C9E8E4FFFFFF72F2C35A4829D7975F5E5B4158C389D24883EC08C70100000000C64104004883C408C389F64156415541544D89CC555756534C89C34883EC20410FB64104418800418B3183FE010F84AB00000073434863D24D89C54889CE488D3C114839FE0F84A50100000FB62E4883C601E8C601000083ED2B4080FD5077E2480FBEED0FB6042884C00FBED078D3C1E20241885500EB7383FE020F841C01000031C083FE03740F4883C4205B5E5F5D415C415D415EC34863D24D89C54889CE488D3C114839FE0F84CA0000000FB62E4883C601E86401000083ED2B4080FD5077E2480FBEED0FB6042884C078D683E03F410845004983C501E964FFFFFF4863D24D89C54889CE488D3C114839FE0F84E00000000FB62E4883C601E81D01000083ED2B4080FD5077E2480FBEED0FB6042884C00FBED078D389D04D8D7501C1E20483E03041885501C1F804410845004839FE747B0FB62E4883C601E8DD00000083ED2B4080FD5077E6480FBEED0FB6042884C00FBED078D789D0C1E2064D8D6E0183E03C41885601C1F8024108064839FE0F8536FFFFFF41C7042403000000410FB6450041884424044489E84883C42029D85B5E5F5D415C415D415EC34863D24889CE4D89C6488D3C114839FE758541C7042402000000410FB60641884424044489F04883C42029D85B5E5F5D415C415D415EC341C7042401000000410FB6450041884424044489E829D8E998FEFFFF41C7042400000000410FB6450041884424044489E829D8E97CFEFFFF56574889CF4889D64C89C1FCF3A45F5EC3E8500000003EFFFFFF3F3435363738393A3B3C3DFFFFFFFEFFFFFF000102030405060708090A0B0C0D0E0F10111213141516171819FFFFFFFFFFFF1A1B1C1D1E1F202122232425262728292A2B2C2D2E2F3031323358C3' Else Local $Opcode = '0x89C0608B7424248B7C2428FCB28031DBA4B302E86D00000073F631C9E864000000731C31C0E85B0000007323B30241B010E84F00000010C073F7753FAAEBD4E84D00000029D97510E842000000EB28ACD1E8744D11C9EB1C9148C1E008ACE82C0000003D007D0000730A80FC05730683F87F770241419589E8B3015689FE29C6F3A45EEB8E00D275058A164610D2C331C941E8EEFFFFFF11C9E8E7FFFFFF72F2C32B7C2428897C241C61C389D28B442404C70000000000C6400400C2100089F65557565383EC1C8B6C243C8B5424388B5C24308B7424340FB6450488028B550083FA010F84A1000000733F8B5424388D34338954240C39F30F848B0100000FB63B83C301E8CD0100008D57D580FA5077E50FBED20FB6041084C00FBED078D78B44240CC1E2028810EB6B83FA020F841201000031C083FA03740A83C41C5B5E5F5DC210008B4C24388D3433894C240C39F30F84CD0000000FB63B83C301E8740100008D57D580FA5077E50FBED20FB6041084C078DA8B54240C83E03F080283C2018954240CE96CFFFFFF8B4424388D34338944240C39F30F84D00000000FB63B83C301E82E0100008D57D580FA5077E50FBED20FB6141084D20FBEC278D78B4C240C89C283E230C1FA04C1E004081189CF83C70188410139F374750FB60383C3018844240CE8EC0000000FB654240C83EA2B80FA5077E00FBED20FB6141084D20FBEC278D289C283E23CC1FA02C1E006081739F38D57018954240C8847010F8533FFFFFFC74500030000008B4C240C0FB60188450489C82B44243883C41C5B5E5F5DC210008D34338B7C243839F3758BC74500020000000FB60788450489F82B44243883C41C5B5E5F5DC210008B54240CC74500010000000FB60288450489D02B442438E9B1FEFFFFC7450000000000EB9956578B7C240C8B7424108B4C241485C9742FFC83F9087227F7C7010000007402A449F7C702000000740566A583E90289CAC1E902F3A589D183E103F3A4EB02F3A45F5EC3E8500000003EFFFFFF3F3435363738393A3B3C3DFFFFFFFEFFFFFF000102030405060708090A0B0C0D0E0F10111213141516171819FFFFFFFFFFFF1A1B1C1D1E1F202122232425262728292A2B2C2D2E2F3031323358C3' EndIf Local $AP_Decompress = (StringInStr($Opcode, "89C0") - 3) / 2 Local $B64D_Init = (StringInStr($Opcode, "89D2") - 3) / 2 Local $B64D_DecodeData = (StringInStr($Opcode, "89F6") - 3) / 2 $Opcode = Binary($Opcode) Local $CodeBufferMemory = _MemVirtualAlloc(0, BinaryLen($Opcode), $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) Local $CodeBuffer = DllStructCreate("byte[" & BinaryLen($Opcode) & "]", $CodeBufferMemory) DllStructSetData($CodeBuffer, 1, $Opcode) Local $B64D_State = DllStructCreate("byte[16]") Local $Length = StringLen($Code) Local $Output = DllStructCreate("byte[" & $Length & "]") DllCall("user32.dll", "none", "CallWindowProc", "ptr", DllStructGetPtr($CodeBuffer) + $B64D_Init, _ "ptr", DllStructGetPtr($B64D_State), _ "int", 0, _ "int", 0, _ "int", 0) DllCall("user32.dll", "int", "CallWindowProc", "ptr", DllStructGetPtr($CodeBuffer) + $B64D_DecodeData, _ "str", $Code, _ "uint", $Length, _ "ptr", DllStructGetPtr($Output), _ "ptr", DllStructGetPtr($B64D_State)) Local $ResultLen = DllStructGetData(DllStructCreate("uint", DllStructGetPtr($Output)), 1) Local $Result = DllStructCreate("byte[" & ($ResultLen + 16) & "]") Local $Ret = DllCall("user32.dll", "uint", "CallWindowProc", "ptr", DllStructGetPtr($CodeBuffer) + $AP_Decompress, _ "ptr", DllStructGetPtr($Output) + 4, _ "ptr", DllStructGetPtr($Result), _ "int", 0, _ "int", 0) _MemVirtualFree($CodeBufferMemory, 0, $MEM_RELEASE) Return BinaryMid(DllStructGetData($Result, 1), 1, $Ret[0]) EndFunc Base64.au3 KrakenAPI.au3 SHA224_256.au3 Link to comment Share on other sites More sharing options...
Danyfirex Posted August 13, 2017 Share Posted August 13, 2017 (edited) Hello. Welcome to AutoIt forum. Here is an implemetation that I've written for you. expandcollapse popup#include <Crypt.au3> #include <Base64.au3> #include <SHA224_256.au3> Global Const $CALG_SHA_512 = 0x0000800e #Region Kraken Const Global $g_sKrakenURL = "https://api.kraken.com" Global $g_sKrakenAPIVersion = "0" #EndRegion Kraken Const #Region keys Global Const $g_sAPIKey = "a8/dt1+Sjw6a8/OspaeKgTvQXjVGDa7MTwtkE8U85oJpX+OThqMjLcSf" ;you can use this for testing, it uses a test account Global Const $g_sAPISecret = "gmJASh6IR57seYYJE5z6qEU5sT7OBm+QPzDBp8/89OnaTNydM7rbsKo0hHbHAfMEW1zcPrN6EPDc0PD2hMEWyQ==" ;you can use this for testing, it uses a test account #EndRegion keys #Region API Test _TestAPI() Func _TestAPI() ;Query Public Local $sResult = KrakenQueryPublic("Time") ;Server Time ConsoleWrite("Time: " & $sResult & @CRLF & @CRLF) ;Query Private $sResult = KrakenQueryPrivate("TradeVolume", "&pair=XXBTZUSD,XXBTZEUR") ;Trade Volume ConsoleWrite("TradeVolume: " & $sResult & @CRLF & @CRLF) $sResult = KrakenQueryPrivate("Balance") ;Get Balance ConsoleWrite("Balance: " & $sResult & @CRLF & @CRLF) EndFunc ;==>_TestAPI #EndRegion API Test #Region Kraken Query Func KrakenQueryPublic($sMethod, $sParameters = "") Local $sURL = StringFormat("/%s/public/%s", $g_sKrakenAPIVersion, $sMethod) Local $oHTTP = ObjCreate("winhttp.winhttprequest.5.1") $oHTTP.Open("POST", $g_sKrakenURL & $sURL, False) $oHTTP.Send(Binary($sParameters)) Local $sReceived = $oHTTP.ResponseText Return $sReceived EndFunc ;==>KrakenQueryPublic Func KrakenQueryPrivate($sMethod, $sParameters = "") Local $sNONCE = _GetNonce() $sParameters = "nonce=" & $sNONCE & $sParameters Local $sURL = StringFormat("/%s/private/%s", $g_sKrakenAPIVersion, $sMethod) Local $sSecretDecoded = _Base64Decode($g_sAPISecret) Local $sNonceParams = $sNONCE & $sParameters Local $bURLBytes = Binary($sURL) Local $sHashNonceParams = _SHA256($sNonceParams) Local $bMessage = $bURLBytes & $sHashNonceParams Local $sSignature = HMACSHA512($sSecretDecoded, $bMessage) Local $oHTTP = ObjCreate("winhttp.winhttprequest.5.1") $oHTTP.Open("POST", $g_sKrakenURL & $sURL, False) $oHTTP.SetRequestHeader("API-Key", $g_sAPIKey) $oHTTP.SetRequestHeader("API-Sign", _Base64EncodeMod($sSignature)) $oHTTP.Send(Binary($sParameters)) Local $sReceived = $oHTTP.ResponseText Return $sReceived EndFunc ;==>KrakenQueryPrivate #EndRegion Kraken Query Func _GetNonce() ;~ Return @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC Return 9 & @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC ;added 9 at start due while testing I added a big nonce number > (@YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC). With another APIkey Use line above (and comment this) EndFunc ;==>_GetNonce Func _Base64EncodeMod($sData) Return StringReplace(_Base64Encode($sData), @LF, "") EndFunc ;==>_Base64EncodeMod Func HMACSHA512($bKey, $bMessage) Local Const $iBlockSize = (512 / 8) Local Const $oconst = 0x5C, $iconst = 0x36 Local $a_opad[$iBlockSize], $a_ipad[$iBlockSize] Local $opad = Binary(''), $ipad = Binary('') If BinaryLen($bKey) > $iBlockSize Then $bKey = _Crypt_HashData($bKey, $CALG_SHA_512) For $i = 1 To BinaryLen($bKey) $a_ipad[$i - 1] = Number(BinaryMid($bKey, $i, 1)) $a_opad[$i - 1] = Number(BinaryMid($bKey, $i, 1)) Next For $i = 0 To $iBlockSize - 1 $a_opad[$i] = BitXOR($a_opad[$i], $oconst) $a_ipad[$i] = BitXOR($a_ipad[$i], $iconst) Next For $i = 0 To $iBlockSize - 1 $ipad &= Binary('0x' & Hex($a_ipad[$i], 2)) $opad &= Binary('0x' & Hex($a_opad[$i], 2)) Next Local $bRet = _Crypt_HashData($ipad & ($bMessage), $CALG_SHA_512) $bRet = _Crypt_HashData($opad & $bRet, $CALG_SHA_512) Return $bRet EndFunc ;==>HMACSHA512 Includes: Includes.zip Saludos Edited October 2, 2017 by Danyfirex notsure, Xandy and Neutro 3 Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
Oleksandr Posted September 26, 2017 Share Posted September 26, 2017 I also have problems with authorization.https://bittrex.com/Home/Apihttps://www.bitstamp.net/api/ Please, help!!! Link to comment Share on other sites More sharing options...
notsure Posted October 2, 2017 Share Posted October 2, 2017 (edited) On 13-8-2017 at 6:07 AM, Danyfirex said: Hello. Welcome to AutoIt forum. Here is an implemetation that I've written for you. expandcollapse popup#include <Crypt.au3> #include <Base64.au3> #include <SHA224_256.au3> Global Const $CALG_SHA_512 = 0x0000800e #Region Kraken Const Global $g_sKrakenURL = "https://api.kraken.com" Global $g_sKrakenAPIVersion = "0" #EndRegion Kraken Const #Region keys Global Const $g_sAPIKey = "a8/dt1+Sjw6a8/OspaeKgTvQXjVGDa7MTwtkE8U85oJpX+OThqMjLcSf" ;you can use this for testing, it uses a test account Global Const $g_sAPISecret = "gmJASh6IR57seYYJE5z6qEU5sT7OBm+QPzDBp8/89OnaTNydM7rbsKo0hHbHAfMEW1zcPrN6EPDc0PD2hMEWyQ==" ;you can use this for testing, it uses a test account #EndRegion keys #Region API Test _TestAPI() Func _TestAPI() ;Query Public Local $sResult = KrakenQueryPublic("Time") ;Server Time ConsoleWrite("Time: " & $sResult & @CRLF & @CRLF) ;Query Private $sResult = KrakenQueryPrivate("TradeVolume", "&pair=XXBTZUSD,XXBTZEUR") ;Trade Volume ConsoleWrite("TradeVolume: " & $sResult & @CRLF & @CRLF) $sResult = KrakenQueryPrivate("Balance") ;Get Balance ConsoleWrite("Balance: " & $sResult & @CRLF & @CRLF) EndFunc ;==>_TestAPI #EndRegion API Test #Region Kraken Query Func KrakenQueryPublic($sMethod, $sParameters = "") Local $sURL = StringFormat("/%s/public/%s", $g_sKrakenAPIVersion, $sMethod) Local $oHTTP = ObjCreate("winhttp.winhttprequest.5.1") $oHTTP.Open("POST", $g_sKrakenURL & $sURL, False) $oHTTP.Send(Binary($sParameters)) Local $sReceived = $oHTTP.ResponseText Return $sReceived EndFunc ;==>KrakenQueryPublic Func KrakenQueryPrivate($sMethod, $sParameters = "") Local $sNONCE = _GetNonce() $sParameters = "nonce=" & $sNONCE & $sParameters Local $sURL = StringFormat("/%s/private/%s", $g_sKrakenAPIVersion, $sMethod) Local $sSecretDecoded = _Base64Decode($g_sAPISecret) Local $sNonceParams = $sNONCE & $sParameters Local $bURLBytes = Binary($sURL) Local $sHashNonceParams = _SHA256($sNonceParams) Local $bMessage = $bURLBytes & $sHashNonceParams Local $sSignature = HMACSHA512($sSecretDecoded, $bMessage) Local $oHTTP = ObjCreate("winhttp.winhttprequest.5.1") $oHTTP.Open("POST", $g_sKrakenURL & $sURL, False) $oHTTP.SetRequestHeader("API-Key", $g_sAPIKey) $oHTTP.SetRequestHeader("API-Sign", _Base64EncodeMod($sSignature)) $oHTTP.Send(Binary($sParameters)) Local $sReceived = $oHTTP.ResponseText Return $sReceived EndFunc ;==>KrakenQueryPrivate #EndRegion Kraken Query Func _GetNonce() ;~ Return @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC Return 9 & @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC ;added 9 at start due while testing I added a big nonce number > (@YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC). With another APIkey Use line above (and comment this) EndFunc ;==>_GetNonce Func _Base64EncodeMod($sData) Return StringReplace(_Base64Encode($sData), @LF, "") EndFunc ;==>_Base64EncodeMod Func HMACSHA512($bKey, $bMessage) Local Const $iBlockSize = (1024 / 8) Local Const $oconst = 0x5C, $iconst = 0x36 Local $a_opad[$iBlockSize], $a_ipad[$iBlockSize] Local $opad = Binary(''), $ipad = Binary('') If BinaryLen($bKey) > $iBlockSize Then $bKey = _Crypt_HashData($bKey, $CALG_SHA_512) For $i = 1 To BinaryLen($bKey) $a_ipad[$i - 1] = Number(BinaryMid($bKey, $i, 1)) $a_opad[$i - 1] = Number(BinaryMid($bKey, $i, 1)) Next For $i = 0 To $iBlockSize - 1 $a_opad[$i] = BitXOR($a_opad[$i], $oconst) $a_ipad[$i] = BitXOR($a_ipad[$i], $iconst) Next For $i = 0 To $iBlockSize - 1 $ipad &= Binary('0x' & Hex($a_ipad[$i], 2)) $opad &= Binary('0x' & Hex($a_opad[$i], 2)) Next Local $bRet = _Crypt_HashData($ipad & ($bMessage), $CALG_SHA_512) $bRet = _Crypt_HashData($opad & $bRet, $CALG_SHA_512) Return $bRet EndFunc ;==>HMACSHA512 Includes: Includes.zip Saludos What does the $oHTTP.send do with $parameters? I'm trying to get this to work for bittrex, But i get invalid signature when i use; Global Const $CALG_SHA_512 = 0x0000800e #Region Bittrex Const Global $g_bittrexURL = "https://bittrex.com/api" Global $g_bittrexAPIVersion = "v1.1" #EndRegion Bittrex Const Func BittrexQueryPrivate($sMethod, $sParameters = "") Local $sNONCE = _GetNonce() $sParameters = "nonce=" & $sNONCE & $sParameters Local $sURL = StringFormat("/%s/account/%s", $g_bittrexAPIVersion, $sMethod) Local $oHTTP = ObjCreate("winhttp.winhttprequest.5.1") $FullURL = $g_bittrexURL & $sURL & "?apikey=" & $g_sAPIKey & "&nonce=" & $sNONCE Local $sSignature = HMACSHA512($g_sAPISecret, $FullURL) ;bittrex demands GET $oHTTP.Open("GET", $FullURL, False) $oHTTP.SetRequestHeader("apisign", _Base64EncodeMod($sSignature)) ;sup with this? : $oHTTP.Send(Binary($sParameters)); Local $sReceived = $oHTTP.ResponseText Return $sReceived EndFunc ;==>BittrexQueryPrivate $FULLURL will become; https://bittrex.com/api/v1.1/account/getbalances?apikey=*APIKEYHERE*&nonce=20171002164018019 This responds with; Balance: {"success":false,"message":"INVALID_SIGNATURE","result":null} This also happens when i use the correct $nonce. Func CurrentTime() return _DateDiff('s', "1970/01/01 00:00:00", _NowCalc()) EndFunc Edited October 2, 2017 by notsure Link to comment Share on other sites More sharing options...
Vovsla Posted June 7, 2018 Share Posted June 7, 2018 Includes.zip doesn't work, how can i get includes? Link to comment Share on other sites More sharing options...
Vovsla Posted June 7, 2018 Share Posted June 7, 2018 Oops, it's existing here in au3 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now