2025-05-12 13:28:44 +08:00

123 lines
4.2 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.example.caseData.extend.app;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.*;
@Slf4j
public class Base {
private static final ObjectMapper objectMapper = new ObjectMapper();
/**
* 生成签名
* @param params 需要签名的参数(支持嵌套 Map
* @param secretKey 密钥
* @return 签名字符串
*/
public static String genSignature(Map<String, Object> params, String secretKey) {
try {
// Step 1: 对 Map 进行递归排序
Map<String, Object> sortedMap = sortMapRecursively(params);
// Step 2: 转为 JSON 字符串
String json = objectMapper.writeValueAsString(sortedMap);
// Step 3: 使用 HMAC-SHA256 签名
return hmacSha256(json, secretKey);
} catch (JsonProcessingException e) {
return null;
}
}
/**
* 对 Map<String, Object> 进行递归排序key 排序),支持嵌套 Map 和 List
*/
public static Map<String, Object> sortMapRecursively(Map<String, Object> data) {
Map<String, Object> sortedMap = new TreeMap<>(); // TreeMap 会自动按 key 排序
for (Map.Entry<String, Object> entry : data.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof Map) {
// 如果是嵌套 map递归排序
@SuppressWarnings("unchecked")
Map<String, Object> nestedMap = (Map<String, Object>) value;
sortedMap.put(key, sortMapRecursively(nestedMap));
} else if (value instanceof List) {
// 如果是列表,检查每一项是否是 map如果是则排序
@SuppressWarnings("unchecked")
List<Object> list = (List<Object>) value;
List<Object> sortedList = new ArrayList<>();
for (Object item : list) {
if (item instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> nestedItemMap = (Map<String, Object>) item;
sortedList.add(sortMapRecursively(nestedItemMap));
} else {
sortedList.add(item);
}
}
sortedMap.put(key, sortedList);
} else {
// 普通字段,直接插入
sortedMap.put(key, value);
}
}
return sortedMap;
}
/**
* HMAC-SHA256 加密
*/
private static String hmacSha256(String data, String key) {
try {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
sha256_HMAC.init(secretKeySpec);
byte[] result = sha256_HMAC.doFinal(data.getBytes(StandardCharsets.UTF_8));
// 转为 16 进制字符串
StringBuilder hexString = new StringBuilder();
for (byte b : result) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
} catch (Exception e) {
return null;
}
}
/**
* 发送 POST JSON 请求
* @param url 请求地址
* @param jsonData JSON 字符串
* @param headers 请求头
* @return 响应字符串
*/
public String postJson(String url, String jsonData, Map<String, String> headers) {
HttpRequest request = HttpRequest.post(url)
.body(jsonData)
.header("Content-Type", "application/json");
if (headers != null) {
headers.forEach(request::header);
}
try (HttpResponse response = request.execute()) {
return response.body();
}
}
}