关于签名
简介
用于生成API请求输入参数签名的秘钥应由商户安全地管理,不得向他人披露。
生成签名字符串的步骤如下:
- 把所有需要验证的参数,放入一个数组中。
- 按参数名称按照ASCII升序对数组进行排序。只按照参数名称进行排序,而非参数中的值。
- 在生成签名之前,从数组中排除 'sign' 参数本身。
示例
{
"appId": "TEST000001",
"sign": "TEST000001",
"merchantOrderNo": "11126",
"userId": "[email protected]",
"orderAmount": "1000",
"payCurrency": "USD",
"paymentTokens": "USDT,ETH",
"paymentExchange": "16f021b0-f220-4bbb-aa3b-82d423301957,9226e5c2-ebc3-4fdd-94f6-ed52cdce1420"
}
准备签名串的拼接,将格式转换为 parameter_name=parameter_value,用 '&' 连接起来,最后附加密钥(secret)。结果如下所示:
appId=TEST000001&merchantOrderNo=11126&orderAmount=1000&payCurrency=USD&paymentExchange=16f021b0-f220-4bbb-aa3b-82d423301957,9226e5c2-ebc3-4fdd-94f6-ed52cdce1420&paymentTokens=USDT,ETH&[email protected]&key=***************W0b5nCak
从准备好的签名字符串继续操作,使用SHA-512算法生成最终的签名,并将其改为大写字母。签名的结果如下:
3962E8FF2ABD24B806D744C6630B95A05855A2AB86944CCF52009D6E2582787EB0F34CFF323843DDA55B148D770390598AF335DDBECC61D702AA1A87EE93D
生成签名代码示例
import java.io.*;
import java.net.*;
import java.security.*;
import java.util.*;
public class Sha512Signer {
public static String sha512Sign(Map<String, String> dataMap, String secretKey) throws NoSuchAlgorithmException {
List<String> keys = new ArrayList<>(dataMap.keySet());
Collections.sort(keys);
StringBuilder queryString = new StringBuilder();
for (String key : keys) {
queryString.append(key).append("=").append(dataMap.get(key)).append("&");
}
queryString.append("key=").append(secretKey);
String stringToSign = queryString.toString();
System.out.println("String to sign: " + stringToSign);
MessageDigest md = MessageDigest.getInstance("SHA-512");
byte[] hash = md.digest(stringToSign.getBytes());
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
hexString.append(String.format("%02x", b));
}
return hexString.toString().toUpperCase();
}
public static void main(String[] args) throws Exception {
String url = "https://crypto-payment.alchemytech.cc/XXXXX";
String appId = "XXXXX";
String secret = "XXXXX";
Map<String, String> reqData = new HashMap<>();
reqData.put("merchantOrderNo", "XXXXX");
reqData.put("appId", appId);
String sign = sha512Sign(reqData, secret);
reqData.put("sign", sign);
StringBuilder jsonData = new StringBuilder("{");
for (Map.Entry<String, String> entry : reqData.entrySet()) {
jsonData.append("\"").append(entry.getKey()).append("\":\"").append(entry.getValue()).append("\",");
}
jsonData.deleteCharAt(jsonData.length() - 1);
jsonData.append("}");
sendPostRequest(url, jsonData.toString());
}
private static void sendPostRequest(String url, String jsonData) throws IOException {
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json");
con.setDoOutput(true);
try (OutputStream os = con.getOutputStream()) {
byte[] input = jsonData.getBytes("utf-8");
os.write(input, 0, input.length);
}
int responseCode = con.getResponseCode();
System.out.println("Response Code: " + responseCode);
try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
System.out.println("Response: " + response.toString());
}
}
}
import requests
import hashlib
def sha512_sign(data_dict, secret_key):
sorted_items = sorted(data_dict.items())
query_string = '&'.join(f"{str(k)}={str(v)}" for k, v in sorted_items)
string_to_sign = query_string + f"&key={secret_key}"
print(string_to_sign)
sha512_hash = hashlib.sha512(string_to_sign.encode('utf-8')).hexdigest().upper()
return sha512_hash
urls = "https://crypto-payment.alchemytech.cc/XXXXX"
appId = "XXXXX"
secret = "XXXXX"
req_data = {
"merchantOrderNo":"XXXXX",
"appId":appId,
}
sign = sha512_sign(req_data, secret)
req_data["sign"] = sign
print(requests.post(urls, json=req_data).text)
package main
import (
"bytes"
"crypto/sha512"
"encoding/hex"
"fmt"
"io/ioutil"
"net/http"
"sort"
"strings"
)
func sha512Sign(dataMap map[string]string, secretKey string) string {
keys := make([]string, 0, len(dataMap))
for key := range dataMap {
keys = append(keys, key)
}
sort.Strings(keys)
var queryStrings []string
for _, key := range keys {
queryStrings = append(queryStrings, fmt.Sprintf("%s=%s", key, dataMap[key]))
}
queryString := strings.Join(queryStrings, "&")
stringToSign := queryString + "&key=" + secretKey
fmt.Println("String to sign:", stringToSign)
hash := sha512.New()
hash.Write([]byte(stringToSign))
signature := hex.EncodeToString(hash.Sum(nil))
return strings.ToUpper(signature)
}
func main() {
url := "https://crypto-payment.alchemytech.cc/XXXXX"
appId := "XXXXX"
secret := "XXXXX"
reqData := map[string]string{
"merchantOrderNo": "XXXXX",
"appId": appId,
}
sign := sha512Sign(reqData, secret)
reqData["sign"] = sign
jsonData := "{"
for key, value := range reqData {
jsonData += fmt.Sprintf("\"%s\":\"%s\",", key, value)
}
jsonData = jsonData[:len(jsonData)-1] + "}"
resp, err := http.Post(url, "application/json", bytes.NewBuffer([]byte(jsonData)))
if err != nil {
fmt.Println("Error sending request:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response:", err)
return
}
fmt.Println("Response:", string(body))
}
Updated about 1 month ago