contra

Message signing for kraken.com API

4 posts in this topic

#1 ·  Posted

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:

#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

#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

; -----------------------------------------------------------------------------
; 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 &= 'UVOfCXzK0ijRBlTbKonpbIquchBO6DbMu1bpuGYVyVKSCu/q+QA0VbPMTIZCHWRPClmK8ZOCxI2PZDXwkDIDvDw4IRsue1DJHUTLxMws8Y77BFIaysRIsCcfqXtlwDMU2Oy0/dCB6AEsAQgMnMCXGA+h/Yt8SRDIaPXLx0wvKegDDJk8Xi+7Rd5ZxEQTpVOS5zMeIlUK0tcJcC9YmS0h2IuYQQM4cFI3CfxtLE0JeuD+Id/JCAH4Hs+AC63vSptEGQ4WMu0BlfFani5Ysgs8PjH9ZA9QFgjX922pfoMitejMJOVSE58s1rYY0kjCovmiCu8DLDrnnlmUDAUyIDoRhUHnUu2X/rn6lFvpXs1xLCH/LgDBERMNOFOrpRcpAfqNTAiO/aaWmPPYKBICQsnmGrLGVtQb6yo0JhYRULORLtV6MgrFYP4EK7qZWRRPkxPUXz00SqJNTWhYqkEcYLQD0hKWQBtfHBlcSTgsS7e46ymd+IDS/oj2zUULPge3tDJxcwplmeD6QCGyCcLWWUU/JdWSQ1be7C7uoptT6JbtVlGhAWUA3llVMhjqVhoyHCuFbRBdgyYjEPIrzqYnEuoo0xgiqIbdS80lNF5n5WyPM+4KxMPsqCbXxN/stE8xnssLfJAlGGDbuwokanZXqnAzIdUNAXiLvpe90gkiGYEIAjtn++qvIJIkCfNNQiHTVuRNJJJSxbS+62VDHh4iqjTxnwoB3QshqEuiczHbixIouApEDLIjaDKsl/OM0QH5aJLf4CAcG9HyzGDIvDsuyTDCgcrTMfuWMEMh604TGqNA1kCnyyPNqOvep8sXaTIe+lSSaJ6zCssC7oox3isaFg+DZwnDZ34K24zCHsnnMOq7Yaz7/maJT8si7955z6SDJ7mRGBT0lTymq4Qs0kAbmBl34rSXafo0iKmFLC1ykhSTlS6nzdcZBKzymLLeiRXqmnypa0MERh+lGusJfQ6i1WorFKkSLMTl47xFmAWlpzUhLEQUSjCgcvhcUuajyP9kxkw01JQFE6Hov6JakDYKpyc1DQ0y2h7m3o5svw22NkimU0s7hcAkSPUsQ7jfTxyXW4q9SvEtwoCiqzQf2r+BdxBplJ9IwcuRz8vabN6ECt5IbTGZOE6wKRCtZPfjqC3SSo8ArqwrS2b8qIIkqPPGbwuBkN0ywhPKC1AJrZupVSD9BQhTY8qSQag/C2vaUQYQ8hxsLSm7qlf7mSxDxBc8qNn1NOpi8nOfFcq00rTw1aohcdWiDN5QrRq3UKhV+jmU1s22mx8l5N/kNJeSkGL/ctFrLCIAAHCLS8K1MlhiyVlhENZ5ihu7QrMOJxkaRH5OaXlXEzHIKwlp/Sf6x9SYwUUUB8vV+qhOyi+0RSAiiDAF8ok+OKArzcGRziruIdYYEBgMzjC+t0pqBRIM87Mq/T6Mw/kMLE8uzBEGl6WsKKmjHqNRVMfWkKFPiT6JDAHo+z5iIfd0fFHWUh3V7F9NzTATPDiicSPV6fM2kyyncSAc7gWG9UrAQsxHuCkcxOQsIiARGA8jLLLW13aDWhrE1mMAlBUZ6JLRpLUvMe0tLgw6J9OaxO1bC8Fbwlzf1N1FxSnEaOlPje87KKvVglggV8XDJyjlgZASSALJxbpEE79DHb3IKEQcIhQeQijIx8T2KCCArC3t7Zk1NKc84Ekh9Z+ScA/G/mm9Zfaov7RUGn60CaTXhTUrqLat9jJ8ZFkHZh58T82KqyHO7j/km1Pd4BMQnzyx4w5KDgooz/Bj+CHYAbacHYU1DvRrJuoipPYlAcPotM0GnvMmwxfotqhECu2jHMRIDRcCiKkxa8UgWVIUxgsH0EQJwKboCpeFIO4sizy1qf3GuKNnNFgSlVQXbJAMySDYT91F5euwIE0RRxMiIEUKU8sB1WeX0PCNvDkXcKBqBpoh0BidDZXuGaqjSaqkQKAYV9iqXbFFn6Ijq4aznSkeWOpA2PCZ06GtrUxbl69eSeDEBVLIN320mzQTS6IckVc8QgUwmqQaPlkGJeFS3kxIxYkG+tLJHrQwFsqkGaOl'
                $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

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Hello. Welcome to AutoIt forum. Here is an implemetation that  I've written for you. 

 

#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 by Danyfirex
3 people like this

Share this post


Link to post
Share on other sites

#4 ·  Posted (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. 

 

#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 by notsure

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