II. Signature Authentication Mechanism
API Keys
Name |
Description |
apiKey |
The API key assigned to the merchant |
apiSecret |
The API secret assigned to the merchant. The API key and secret are confidential. Please keep them safe and do not disclose them. They are only used for generating signatures and should not be passed as parameters. |
Name |
Required |
Description |
API-KEY |
Y |
The API key assigned to the merchant |
API-SIGNATURE |
Y |
Signature generated using the signature algorithm below |
API-TIMESTAMP |
Y |
UNIX millisecond timestamp when the request is made |
Content-Type |
N |
Mandatory for all POST requests, value must be application/json |
Signature Algorithm
The value of API-SIGNATURE is obtained by applying the HMAC-SHA256 signature algorithm to request_content + "&" + timestamp
using the apiSecret
key.
Where:
- For GET requests:
All non-empty request parameters are sorted in alphabetical order by parameter name. The sorted parameters are
concatenated into a string
request_content
in the format of parameter name and parameter value.
For example: request_content = "param1=value1¶m2=value2¶m3=value3"
- For POST requests:
Convert the request body into a JSON string to get
request_content
.
For example: request_content = "{"fiatAmt":20,"fiatCurrency":"USD"}"
- The value of
timestamp
is the same as the API-TIMESTAMP request header, which is a millisecond-level timestamp.
- String to be signed:
source = request_content + "&" + timestamp
Code Example
Example of Generating Signature for GET Request:
public static void main(String[] args) {
Map<String, String> map = new LinkedHashMap<>();
map.put("content", "12345");
map.put("name", "test");
long timestamp = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli();
String sign = String.join("&", getSignContentForGET(map), String.valueOf(timestamp));
System.out.println(EncryptionUtils.HMACSHA256(sign, "apiSecret"));
}
private static String getSignContentForGET(Map<String, String> queryParams) {
StringBuilder sb = new StringBuilder();
TreeMap<String, String> treeMap = new TreeMap<>();
treeMap.putAll(queryParams);
for (Map.Entry<String, String> entry : treeMap.entrySet()) {
if (entry.getValue() != null) {
sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
}
String signStr = sb.toString();
signStr = signStr.substring(0, signStr.length() - 1);
return signStr;
}
Example of Generating Signature for POST Request:
public static void main(String[] args) {
Map<String, String> map = new LinkedHashMap<>();
map.put("content", "12345");
map.put("name", "test");
long timestamp = System.currentTimeMillis();
String sign = String.join("&", getSignContentForPost(map), String.valueOf(timestamp));
System.out.println(EncryptionUtils.HMACSHA256(sign, "apiSecret"));
}
private static String getSignContentForPost(Map<String, String> body) {
return JSON.toJSONString(body);
}
Signature Algorithm Utility Class:
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class EncryptionUtils {
public static String HMACSHA256(String data, String secretKey) {
try {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] array = sha256_HMAC.doFinal(data.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : array) {
sb.append(String.format("%02x", b & 0xff));
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}