关于签名

简介

🚧

用于生成API请求输入参数签名的秘钥应由商户安全地管理,不得向他人披露。

生成签名字符串的步骤如下:

  1. 把所有需要验证的参数,放入一个数组中。
  2. 按参数名称按照ASCII升序对数组进行排序。只按照参数名称进行排序,而非参数中的值。
  3. 在生成签名之前,从数组中排除 'sign' 参数本身。

示例

{ "appId": "TEST000001", "sign": "TEST000001", "merchantOrderNo": "11126", "userId": "123456789@qq.com", "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&userId=505884978@qq.com&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)) }

Did this page help you?