Translating Python/JS to Java - JSON & HMAC

455 Views Asked by At

I am trying to translate the following Python example into Java code, but was getting an error around the format of the HTTP post and/or the HMAC signature I have created. If anyone could point at which part I could have possibly done wrong, it would be super helpful. Thank you!

Original Python example:

    PAYLOAD = {
      "access_token": ACCESS_TOKEN,
      "price": 500000,
      "qty": 0.1,
      "currency", "btc"
    }

    def get_encoded_payload(payload):
      payload[u'nonce'] = int(time.time()*1000)

      dumped_json = json.dumps(payload)
      encoded_json = base64.b64encode(dumped_json)
      return encoded_json

    def get_signature(encoded_payload, secret_key):
      signature = hmac.new(str(secret_key).upper(), str(encoded_payload), hashlib.sha512);
      return signature.hexdigest()

    def get_response(url, payload):
      encoded_payload = get_encoded_payload(payload)
      headers = {
        'Content-type': 'application/json',
        'X-COINONE-PAYLOAD': encoded_payload,
        'X-COINONE-SIGNATURE': get_signature(encoded_payload, SECRET_KEY)
      }
      http = httplib2.Http()
      response, content = http.request(URL, 'POST', headers=headers, body=encoded_payload)
      return content

    def get_result():
      content = get_response(URL, PAYLOAD)
      content = json.loads(content)

      return content

    if __name__   == "__main__":
        print get_result()

Original JS example:

    var crypto = require('crypto');
var request = require('request');
var ACCESS_TOKEN = '';
var SECRET_KEY = '';
var url = 'https://api.coinone.co.kr/v2/order/limit_buy/';
  var payload = {
  "access_token": ACCESS_TOKEN,
  "price": 500000,
  "qty": 0.1,
  "currency": "btc",
  "nonce": Date.now()
};

payload = new Buffer(JSON.stringify(payload)).toString('base64');

var signature = crypto
  .createHmac("sha512", SECRET_KEY.toUpperCase())
  .update(payload)
  .digest('hex');

var headers = {
  'content-type':'application/json',
  'X-COINONE-PAYLOAD': payload,
  'X-COINONE-SIGNATURE': signature
};

var options = {
  url: url,
  headers: headers,
  body: payload
};

request.post(options,
  function(error, response, body) {
    console.log(body);
});

My code in Java:

    long nonce = (new Date()).getTime();
    JSONObject json = new JSONObject();
    json.put("currency", "BTC");
    json.put("price", 3000000);
    json.put("qty", 0.01);
    json.put("access_token", publicKey);
    json.put("nonce", nonce);

    System.out.println(json.toString());

    Client client = ClientBuilder.newClient();
    Entity<String> payload = Entity.json(json.toString());
    String message = json.toString(); 
    Response response = client.target(baseAddress+apiAddress)
      .request(MediaType.APPLICATION_JSON_TYPE)
      .header("content-type", "application/json")
      .header("accept", "application/json")
      .header("X-COINONE-PAYLOAD", payload)
      .header("X-COINONE-SIGNATURE", CreateToken(message, privateKey.toUpperCase()))
      .post(payload);

    String body = response.readEntity(String.class);
    System.out.println(body);

    ///////////
    private static String CreateToken(String message, String secretKey)
{
    String hash = "";
    try {    

        Mac sha512_HMAC = Mac.getInstance("HmacSHA512");
        SecretKeySpec secret_key = new SecretKeySpec(secretKey.getBytes(), "HmacSHA512");
        sha512_HMAC.init(secret_key);

        hash = Base64.encodeBase64String(sha512_HMAC.doFinal(message.getBytes()));

    }
    catch (Exception e){
        System.out.println("Error");
    }
    System.out.println(hash);
    return hash;
}

It returns the following message: {"errorCode":"130","errorMessage":"V2 API Nonce value must be a positive integer","result":"error"}

But this message seems to be a generic one - when input other nonce values, it also returns the same message

1

There are 1 best solutions below

0
On

Your message(payload) and hash(signature) are wrong...

Example:

String payload = Base64.encodeBase64String(message.getBytes("UTF-8"));
String signature = CreateToken(payload, key.toUpperCase());

---------
private static String CreateToken(String message, String secretKey){
String hash = "";
try {    

    Mac sha512_HMAC = Mac.getInstance("HmacSHA512");
    SecretKeySpec secret_key = new SecretKeySpec(secretKey.getBytes(), "HmacSHA512");
    sha512_HMAC.init(secret_key);

// hash = Base64.encodeBase64String(sha512_HMAC.doFinal(message.getBytes()));
hash = Hex.encodeHexString(sha512_HMAC.doFinal(message.getBytes()));

}
catch (Exception e){
    System.out.println("Error");
}
System.out.println(hash);
return hash;

}