Trying to tackle the Kraken API. Using ColdFusion 2016. I have a few tries in here, but can't seem to quite get it. So testing message, message2, message3 attempts.
https://docs.kraken.com/rest/#section/Authentication/Headers-and-Signature
HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key
EXPECTED RESULT:
4/dpxb3iT4tp/ZCVEwSnEsLxx0bqyhLpdfOpc6fn7OR8+UClSV5n9E6aSS8MPtnRfp32bAb0nmbRn6H8ndwLUQ==
<cfset _key = "APIKEY">
<cfset _s = "kQH5HW/8p1uGOVjbgWA7FunAmGO8lsSUXNsu3eow76sz84Q18fWxnyRzBHCd3pd5nE9qa99HAZtuZuj6F">
<cfset nonce = "1616492376594">
<cfset payload = "nonce=1616492376594&ordertype=limit&pair=XBTUSD&price=37500&type=buy&volume=1.25">
<cfset URIPath = "/0/private/AddOrder">
<cfscript>
apiKey = "#_key#";
apiSecret = "#_s#";
theKeyBytes = charsetDecode(#_s#, "UTF-8");
_Secret64 = toBase64(#_s#);
// get_kraken_signature(urlpath, data, secret):
h = '#uripath#' & #payload#;
_hash = hmac(h, theKeyBytes, "HMACSHA256");
//HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key
//SHA256(nonce + POST data))
_256 = hmac(payload, "HMACSHA256");
_sign = hmac(payload, theKeyBytes, "HMACSHA256");
// HMAC-SHA512 of (URI path + SHA256(nonce + POST data))
message = '#uripath#' & #_256#;
message2 = '#uripath#' & #_256# & #_Secret64#;
message3 = '#uripath#' & #_sign# & #_Secret64#;
_512 = hmac(#message#, "HMACSHA512");
_512_2 = hmac(#message2#, "HMACSHA512");
_512_3 = hmac(#message3#, "HMACSHA512");
_512_H = hmac(#_hash#, "HMACSHA512");
S_H = hmac(#_512_h#, #_s#, "HmacSHA512");
H64 = toBase64(binaryDecode(#s_h#, "hex"));
// base64 decoded secret API key
_64 = toBase64(#_512#);
S_Hex = hmac(#_512#, #_s#, "HmacSHA512");
Hex64 = toBase64(binaryDecode(#s_hex#, "hex"));
S_Hex2 = hmac(#_512_2#, #_s#, "HmacSHA512");
Hex642 = toBase64(binaryDecode(#s_hex2#, "hex"));
S_Hex3 = hmac(#_512_3#, #_s#, "HmacSHA512");
Hex643 = toBase64(binaryDecode(#s_hex3#, "hex"));
</cfscript>
EXPECTED RESULT:
4/dpxb3iT4tp/ZCVEwSnEsLxx0bqyhLpdfOpc6fn7OR8+UClSV5n9E6aSS8MPtnRfp32bAb0nmbRn6H8ndwLUQ==
Hex64 Gets:
w1PXl7IDLs1Pri1Vf++UcLFWIFedkxgpceFVkVFbxt7wvjj/Q0wtwwLSMJxV7bMOdFi+BEN3lHuX+CWRx2SxAQ==
Hex642 Gets:
Zxd+96KuI3wSQJ/b0l79djB1M7FMsczoWOfs9Ha5YWIC6sc6uryEGn4MgkcHnF/ndsxDQ2y/jSHl0RxTIuc7PA==
Hex643 Gets:
5KCKhgRGexBPF7SgnSB5G0m3bu+2ecf4fAOndDG0pvYLh0PeWC1nWodi5szigcGU4TyLLb80jPNAR7OmK0t0Sw==
Taking this question as an exercise, I've managed to translate the python function from KrakenAPI docs to CFML script. That function should help you and others with a practical solution. Also publishing it here for my own documentation:
<cfscript>
public string function getKrakenSignature( urlpath, postdata, nonce, secretAsBase64) localmode=true {
// assign arguments to local variables
urlpath= arguments.urlpath;
nonce= arguments.nonce;
postdata = arguments.postdata;
secretAsBase64= arguments.secretAsBase64;
// convert urlpath to a binary Hex representation
urlpathBinary= toBinary( toBase64( urlpath ));
urlpathBinaryAsHex= BinaryEncode( urlpathBinary, "HEX");
// convert secret to binary
secretBinary= ToBinary( arguments.secretAsBase64 );
// concatenate nonce and postdata
noncePostdata = nonce & postdata;
//get binary digest as Hex representation
noncePostdataDigestBinaryAsHex= hash( noncePostdata, "SHA-256" );
// concatenate urlPath binary (hex) and oncePostdataDigest binary (hex)
messageBinaryAsHex= urlpathBinaryAsHex & noncePostdataDigestBinaryAsHex;
// convert message hex representation to binary
messageBinary= BinaryDecode( messageBinaryAsHex, "HEX");
// sign the message with hmac function
messageHmacDigestBinaryAsHex = hmac( messageBinary, secretBinary, "HMACSHA512");
messageHmacDigestBinary=BinaryDecode( messageHmacDigestBinaryAsHex, "HEX");
return binaryEncode( messageHmacDigestBinary, "base64" );
}
encodedPayLoad="nonce=1616492376594&ordertype=limit&pair=XBTUSD&price=37500&type=buy&volume=1.25";
nonce="1616492376594";
api_sec = "kQH5HW/8p1uGOVjbgWA7FunAmGO8lsSUXNsu3eow76sz84Q18fWxnyRzBHCd3pd5nE9qa99HAZtuZuj6F1huXg==";
urlpath="/0/private/AddOrder";
signature = getKrakenSignature( urlpath, encodedPayLoad, nonce, api_sec);
writeoutput( signature );
</cfscript>
Find a gist here at tryCf.com