Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
173 views
in Technique[技术] by (71.8m points)

java - Can't signing a Message using sha512 in python at iconomi

I am trying to send an authentificated message over an API at iconomi.com. I am used to sign message when dealing with other exchange API, but can't be authentificated with this specific one.

I read the official documentation for authentification:

You generate the ICN-SIGN header by creating a sha512 HMAC using the base64-decoded secret key on the prehash string timestamp + method + requestPath + body (where + represents string concatenation) and base64-encode the output, where:

the timestamp value is the same as the ICN-TIMESTAMP header. the body is the request body string or omitted if there is no request body (typically for GET requests). method must always be in upper case

Example: base64_encode(HMAC_SHA512(secret_key, timestamp + upper_case(method) + requestPath + body))

I found also a java client example on the official github, please see bellow signature generation in java :

private String generateServerDigest(String method, String uri, long timestamp, String body) {
    //return timestamp + request.getMethodValue() + uri + body;
    String checkDigestString = timestamp + method + uri + body;//  "GET+/v1/daa-list+123123123"; //timestamp in epoch milliseconds

    // hash server composited digest with algorithm and apikeys secret
    SecretKeySpec signingKey = new SecretKeySpec(apiSecret.getBytes(), "HmacSHA512");
    Mac mac;
    try {
        mac = Mac.getInstance(signingKey.getAlgorithm());
        mac.init(signingKey);
    } catch (NoSuchAlgorithmException | InvalidKeyException e) {
        log.warn("Could not ={}", signingKey.getAlgorithm());
        return null;
    }

    return Base64.getEncoder().encodeToString(mac.doFinal(checkDigestString.getBytes()));
}

Please note that checkDigestString code timestamp + method + uri + body and comment GET+/v1/daa-list+123123123 are already different on the official doc.


And this is my python implementation attempt :

def sign(timestamp,method,requestPath,body):
    global api_secret
    base64_decoded_secret_key = base64.b64decode(api_secret)
    content_to_hash = (str(timestamp) + method.upper() + requestPath + body).encode('utf-8')
    sign_digest = hmac.new(base64_decoded_secret_key, content_to_hash , hashlib.sha512).digest()    
    return base64.b64encode(sign_digest).decode('utf-8')

When I try this signature method with requestPath = "/v1/user/balance" (which required to be authentificated), it fail without error...


Does any one used with both java and python may help me to convert this signature method to python ?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This code will work:

import time,requests
import hashlib,hmac,base64

api_key = "my api key"
api_secret = "my api secret"

defaut_encoding = "utf8"

uri = "https://api.iconomi.com"
requestPath = "/v1/user/balance"
api_url_target = uri+requestPath # https://api.iconomi.com/v1/user/balance
method="GET"
body=""
icn_timestamp = int(1000.*time.time())

message = (str(icn_timestamp) + method.upper() + requestPath + body).encode(defaut_encoding)
signature_digest = hmac.new(api_secret.encode(defaut_encoding), message, hashlib.sha512).digest() #here digest is byte
b64_signature_digest= base64.b64encode(signature_digest).decode(defaut_encoding)

headers_sign= {
    "ICN-API-KEY":api_key,
    "ICN-SIGN":b64_signature_digest,
    "ICN-TIMESTAMP":str(icn_timestamp)
}

s=requests.session()
res = s.get(api_url_target,headers=headers_sign,timeout=3, verify=True).content
print (res)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...