package com.ruoyi.im.util; import java.security.MessageDigest; import java.util.*; /** * 支付签名工具类 */ public class PaySignUtil { /** * 生成签名 * @param params 参数Map * @param key 商户密钥 * @return 签名值 */ public static String generateSign(Map params, String key) { try { // 第一步:参数按ASCII码排序 String stringA = createSignString(params); // 第二步:拼接key String stringSignTemp = stringA + "&key=" + key; // 第三步:MD5加密并转为大写 return md5(stringSignTemp).toUpperCase(); } catch (Exception e) { throw new RuntimeException("生成签名失败", e); } } /** * 验证签名 * @param params 参数Map * @param key 商户密钥 * @param sign 待验证签名 * @return 验证结果 */ public static boolean verifySign(Map params, String key, String sign) { String generatedSign = generateSign(params, key); return generatedSign.equals(sign); } /** * 创建待签名字符串 */ private static String createSignString(Map params) { // 移除sign参数 Map signParams = new HashMap<>(params); signParams.remove("sign"); // 过滤空值并排序 List keys = new ArrayList<>(); for (Map.Entry entry : signParams.entrySet()) { if (entry.getValue() != null && !entry.getValue().toString().trim().isEmpty()) { keys.add(entry.getKey()); } } // ASCII码排序 Collections.sort(keys); // 拼接字符串 StringBuilder sb = new StringBuilder(); for (int i = 0; i < keys.size(); i++) { String key = keys.get(i); String value = signParams.get(key).toString(); if (i > 0) { sb.append("&"); } sb.append(key).append("=").append(value); } return sb.toString(); } /** * MD5加密 */ private static String md5(String data) throws Exception { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] array = md.digest(data.getBytes("UTF-8")); StringBuilder sb = new StringBuilder(); for (byte item : array) { sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); } return sb.toString(); } }