package com.fzzy.gateway.hx2023.util; import cn.hutool.crypto.digest.MD5; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang3.StringUtils; import javax.servlet.http.HttpServletRequest; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.security.interfaces.RSAPrivateKey; import java.util.*; /** * 签名工具类 */ @Slf4j @Data public class OpenApiSignatureUtils { public static String getMd5Content(String content, String charset) { try { byte[] md5 = MD5.create().digest(content); return new String(md5, charset); } catch (UnsupportedEncodingException e) { log.error("getMd5Content(),exception happens.", e); } return null; } public static String getSignContent(final Map sortedParams) { StringBuffer content = new StringBuffer(); List keys = new ArrayList(sortedParams.keySet()); Collections.sort(keys); int index = 0; for (int i = 0; i < keys.size(); i++) { String key = keys.get(i); String value = sortedParams.get(key); if (key.equals("sign") || key.equals("sign_type")) { continue; } if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(value)) { content.append((index == 0 ? "" : "&") + key + "=" + value); index++; } } return content.toString(); } public static String getSignContentWithQuotes(final Map sortedParams) { StringBuffer content = new StringBuffer(); List keys = new ArrayList(sortedParams.keySet()); Collections.sort(keys); int index = 0; for (int i = 0; i < keys.size(); i++) { String key = keys.get(i); String value = sortedParams.get(key); if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(value)) { content.append((index == 0 ? "" : "&") + key + "=\"" + value + "\""); index++; } } return content.toString(); } public static boolean doCheckV1(String appId, Map params, String charset, String publicKey, String privateKye) throws Exception { String sign = params.get("sign"); String content = getSignCheckContentWithoutSign(params); return doRsaCheckContent(appId, content, sign, charset, publicKey, privateKye); } public static String doSignByBase64(String appId, String content, String charset, String publicKey, String privateKye) throws RuntimeException { try { byte[] signData = OpenApiRsaSigner.encrypt((RSAPrivateKey) OpenApiRsaSigner.getInstance(appId, publicKey, privateKye).getPrivateKey(), content.getBytes(charset)); //return new String(signData, charset); return new String(Base64.encodeBase64(signData), StandardCharsets.UTF_8); } catch (Exception e) { throw new RuntimeException("key=" + appId + ";content=" + content + ";charset=" + charset, e); } } public static String doSignByHex(String appId, String content, String charset, String publicKey, String privateKye) throws RuntimeException { try { byte[] signData = OpenApiRsaSigner.encrypt((RSAPrivateKey) OpenApiRsaSigner.getInstance(appId, publicKey, privateKye).getPrivateKey(), content.getBytes(charset)); //return new String(signData, charset); return new String(Hex.encodeHex(signData)); } catch (Exception e) { throw new RuntimeException("key=" + appId + ";content=" + content + ";charset=" + charset, e); } } public static String doSignByTranscode(String appId, String content, String charset, String publicKey, String privateKye) throws RuntimeException { try { byte[] signData = OpenApiRsaSigner.encrypt((RSAPrivateKey) OpenApiRsaSigner.getInstance(appId, publicKey, privateKye).getPrivateKey(), content.getBytes(charset)); return new String(signData, charset); //return new String(Base64.encodeBase64(signData), StandardCharsets.UTF_8); } catch (Exception e) { throw new RuntimeException("key=" + appId + ";content=" + content + ";charset=" + charset, e); } } public static String getSignCheckContentWithoutSign(Map params) { if (params == null) { return null; } params.remove("sign"); params.remove("sign_type"); StringBuffer content = new StringBuffer(); List keys = new ArrayList(params.keySet()); Collections.sort(keys); for (int i = 0; i < keys.size(); i++) { String key = keys.get(i); String value = params.get(key); content.append((i == 0 ? "" : "&") + key + "=" + value); } return content.toString(); } public static boolean doRsaCheckContent(String appId, String content, String sign, String charset, String publicKey, String privateKye) throws RuntimeException { try { RSAPrivateKey privateKey = (RSAPrivateKey) OpenApiRsaSigner.getInstance(appId, publicKey, privateKye).getPrivateKey(); return OpenApiRsaSigner.verify(content, sign, privateKey); } catch (Exception e) { throw new RuntimeException("key=" + appId + ";content=" + content + ";sign=" + sign + ";charset=" + charset, e); } } public static boolean doCheckByBase64(String appId, String content, String sign, String charset, String publicKey, String privateKye) throws RuntimeException { try { RSAPrivateKey privateKey = (RSAPrivateKey) OpenApiRsaSigner.getInstance(appId, publicKey, privateKye).getPrivateKey(); return OpenApiRsaSigner.verify(content, new String(Base64.decodeBase64(sign), StandardCharsets.UTF_8), privateKey); } catch (Exception e) { throw new RuntimeException("key=" + appId + ";content=" + content + ";sign=" + sign + ";charset=" + charset, e); } } public static boolean doCheckByHex(String appId, String content, String sign, String charset, String publicKey, String privateKye) throws RuntimeException { try { RSAPrivateKey privateKey = (RSAPrivateKey) OpenApiRsaSigner.getInstance(appId, publicKey, privateKye).getPrivateKey(); return OpenApiRsaSigner.verify(content, new String(Hex.decodeHex(sign.toCharArray())), privateKey); } catch (Exception e) { throw new RuntimeException("key=" + appId + ";content=" + content + ";sign=" + sign + ";charset=" + charset, e); } } public static boolean doCheckByTranscode(String appId, String content, String sign, String charset, String publicKey, String privateKye) throws RuntimeException { try { RSAPrivateKey privateKey = (RSAPrivateKey) OpenApiRsaSigner.getInstance(appId, publicKey, privateKye).getPrivateKey(); return OpenApiRsaSigner.verify(content, sign, privateKey); } catch (Exception e) { throw new RuntimeException("key=" + appId + ";content=" + content + ";sign=" + sign + ";charset=" + charset, e); } } /** * 获取请求参数 * * @param request * @return */ public static Map getParameterMap(HttpServletRequest request) { Enumeration parameters = request.getParameterNames(); if (parameters == null) { return new HashMap<>(); } HashMap resultMap = new HashMap<>(); while (parameters.hasMoreElements()) { String key = parameters.nextElement(); String value = request.getParameter(key); resultMap.put(key, value); } return resultMap; } /** * 测试逻辑 * * @param args * @throws UnsupportedEncodingException */ public static void testSign(String[] args) throws UnsupportedEncodingException { Map sortedParams = new HashMap(); sortedParams.put("appId", "6e3d896b71b911eea5e50250f2000002"); // sortedParams.put("method", "test"); // sortedParams.put("format", "json"); // sortedParams.put("charset", "utf-8"); // sortedParams.put("sign_type", "RSA"); // sortedParams.put("timestamp", "2019-01-01 00:00:00"); // sortedParams.put("version", "1.0"); // sortedParams.put("biz_content", "{\"name\":\"张三\",\"age\":18}"); } }