package com.kmall.admin.haikong.utils; import cn.hutool.core.map.MapUtil; import org.apache.commons.lang.StringUtils; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.util.Arrays; import java.util.Map; /** * 仓库系统签名工具类 * @author lhm * @createDate 2021-11-01 */ public class WareSysSignUtils { private WareSysSignUtils() {} private static Map formatUrl(String url) { Map map = MapUtil.newHashMap(); if (org.springframework.util.StringUtils.isEmpty(url)) { return map; } int i = url.lastIndexOf("?"); String paramStr = url.substring(i+1); String[] strings = paramStr.split("&"); for (String string : strings) { int j = string.indexOf("="); String key = string.substring(0, j); if (!"sign".equalsIgnoreCase(key)) { String value = string.substring(j + 1); map.put(key, value); } } return map; } public static String getSignRequest(String url, String body, String secretKey) throws Exception { String sign = signRequest(formatUrl(url), body, secretKey); return url + "&sign=" + sign; } public static String signRequest(Map params, String body, String secretKey) throws Exception { // 1. 第一步,确保参数已经排序 String[] keys = params.keySet().toArray(new String[0]); Arrays.sort(keys); // 2. 第二步,把所有参数名和参数值拼接在一起(包含body体) String joinedParams = joinRequestParams(params, body, secretKey, keys); // 3. 第三步,使用加密算法进行加密(目前仅支持md5算法) byte[] abstractMesaage = digest(joinedParams); // 4. 把二进制转换成大写的十六进制 return byte2Hex(abstractMesaage); } private static String byte2Hex(byte[] bytes) { char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; int j = bytes.length; char[] str = new char[j * 2]; int k = 0; for (byte byte0 : bytes) { str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } return new String(str); } private static byte[] digest(String message) throws Exception { MessageDigest md5Instance = MessageDigest.getInstance("MD5"); md5Instance.update(message.getBytes(StandardCharsets.UTF_8)); return md5Instance.digest(); } private static String joinRequestParams(Map params, String body, String secretKey, String[] sortedKes) { StringBuilder sb = new StringBuilder(secretKey); // 前面加上secretKey for (String key : sortedKes) { if ("sign".equals(key)) { continue; // 签名时不计算sign本身 } else { String value = params.get(key); if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(value)) { sb.append(key).append(value); } } } // 拼接body体 sb.append(body); // 最后加上secretKey sb.append(secretKey); return sb.toString(); } }