package com.walker.pay.payunk.util; import com.walker.infrastructure.ApplicationRuntimeException; import org.apache.commons.codec.binary.Base64; import org.apache.commons.collections4.MapUtils; import org.apache.commons.io.IOUtils; import sun.misc.BASE64Encoder; import sun.security.util.DerInputStream; import sun.security.util.DerValue; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; public class SignUtils { /** * 生成签名 * * @param params 参数个数 * @return {@link String} */ public static String signature(Map params) { String signatures = ""; try { List paramsStr = new ArrayList<>(); for (String key1 : params.keySet()) { if (null != params.get(key1) && !"".equals(params.get(key1)) && !"sign".equals(key1)) { paramsStr.add(key1); } } Collections.sort(paramsStr); StringBuilder sbff = new StringBuilder(); for (String kk : paramsStr) { if (params.get(kk) == null) { continue; } String value = params.get(kk).toString(); if ("".equals(sbff.toString())) { sbff.append(kk).append("=").append(value); } else { sbff.append("&").append(kk).append("=").append(value); } } String str = String.valueOf(sbff); System.out.println(str); signatures = encryptionSign(str); } catch (Exception e) { e.printStackTrace(); } return signatures; } /** * RSA私钥加密 * * @param content 内容 * @return {@link String} */ public static String encryptionSign(String content) { try { Signature signature = Signature.getInstance("SHA1WithRSA"); String publicKeyBase64Str = IOUtils.toString(Thread.currentThread().getContextClassLoader().getResourceAsStream("rsa.pri")); PrivateKey privateKey = pkcs1ToPrivateKey(publicKeyBase64Str); signature.initSign(privateKey); signature.update(content.getBytes(StandardCharsets.UTF_8)); byte[] signed = signature.sign(); return byte2Base64(signed); } catch (Exception e) { throw new ApplicationRuntimeException("加载'rsa.pri'文件错误,可能文件不存在或解析格式错误:" + e.getMessage(), e); } } public static String byte2Base64(byte[] bytes) { BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(bytes); // return Base64.encodeBase64String(bytes); } /** * 读取文件中的私钥 * * @param keyBase64 关键base64 * @return {@link PrivateKey} * @throws Exception 异常 */ public static PrivateKey pkcs1ToPrivateKey(String keyBase64) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); DerInputStream derReader = new DerInputStream(java.util.Base64.getMimeDecoder().decode(keyBase64)); DerValue[] seq = derReader.getSequence(0); BigInteger modulus = seq[1].getBigInteger(); BigInteger publicExp = seq[2].getBigInteger(); BigInteger privateExp = seq[3].getBigInteger(); BigInteger prime1 = seq[4].getBigInteger(); BigInteger prime2 = seq[5].getBigInteger(); BigInteger exp1 = seq[6].getBigInteger(); BigInteger exp2 = seq[7].getBigInteger(); BigInteger crtCoef = seq[8].getBigInteger(); RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef); return keyFactory.generatePrivate(keySpec); // 读取私钥 // FileInputStream privateKeyFileIn = new FileInputStream("E:\video\\privateKey.dat"); // ObjectInputStream privateKeyObjIn = new ObjectInputStream(privateKeyFileIn); // PrivateKey privateKey = (PrivateKey) privateKeyObjIn.readObject(); // privateKeyObjIn.close(); } /** * 读取文件中的公钥 * * @return {@link PublicKey} * @throws Exception 异常 */ public static PublicKey getPublicKey() throws Exception { String publicKeyBase64Str = IOUtils.toString(Thread.currentThread().getContextClassLoader().getResourceAsStream("rsa.pub")); byte[] decodeBase64 = Base64.decodeBase64(publicKeyBase64Str); // 公钥的规则 X509EncodedKeySpec X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(decodeBase64); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePublic(x509EncodedKeySpec); } /** * 验证签名 * * @param params 参数个数 * @return {@link String} */ public static String verify(Map params) { String signatures = ""; try { List paramsStr = new ArrayList<>(); for (String key1 : params.keySet()) { if (null != params.get(key1) && !"".equals(params.get(key1)) && !"sign".equals(key1)) { paramsStr.add(key1); } } Collections.sort(paramsStr); StringBuilder sbff = new StringBuilder(); for (String kk : paramsStr) { if (params.get(kk) == null) { continue; } String value = params.get(kk).toString(); if ("".equals(sbff.toString())) { sbff.append(kk).append("=").append(value); } else { sbff.append("&").append(kk).append("=").append(value); } } String str = String.valueOf(sbff); // BASE64Decoder decoder = new BASE64Decoder(); // byte[] signed = decoder.decodeBuffer(MapUtils.getString(params, "sign")); byte[] signed = Base64.decodeBase64(MapUtils.getString(params, "sign")); Signature sign = Signature.getInstance("SHA1withRSA"); sign.initVerify(getPublicKey()); sign.update(str.getBytes(StandardCharsets.UTF_8)); if (sign.verify(signed)) { return "success"; } } catch (Exception e) { e.printStackTrace(); } return "error"; } }