package com.nq.utils; import java.security.MessageDigest; import java.util.Map; import java.util.TreeMap; public class PaymentSignUtil { /** * 生成签名 * @param params 请求参数Map * @param key 密钥 * @return 签名 */ public static String generateSign(Map params, String key) { try { // 第一步:去除空值参数 Map sortedParams = new TreeMap<>(); for (Map.Entry entry : params.entrySet()) { if (entry.getValue() != null && !entry.getValue().trim().isEmpty()) { sortedParams.put(entry.getKey(), entry.getValue()); } } // 第二步:拼接字符串 StringBuilder stringA = new StringBuilder(); for (Map.Entry entry : sortedParams.entrySet()) { stringA.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); } // 去掉最后一个& if (stringA.length() > 0) { stringA.deleteCharAt(stringA.length() - 1); } // 拼接密钥 String stringB = stringA.toString() + "&key=" + key; // 第三步:MD5并转为小写 MessageDigest md = MessageDigest.getInstance("MD5"); byte[] digest = md.digest(stringB.getBytes("UTF-8")); StringBuilder sign = new StringBuilder(); for (byte b : digest) { sign.append(String.format("%02x", b)); } return sign.toString().toLowerCase(); } catch (Exception e) { throw new RuntimeException("生成签名失败", e); } } /** * 验证返回签名 * @param data 返回数据 * @param key 密钥 * @param sign 返回的签名 * @return 是否验证通过 */ public static boolean verifySign(Map data, String key, String sign) { try { String generatedSign = generateSign(data, key); return generatedSign.equals(sign); } catch (Exception e) { return false; } } }