| | |
| | | package com.dsh.activity.util.wx; |
| | | |
| | | import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder; |
| | | import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier; |
| | | import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner; |
| | | import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials; |
| | | import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator; |
| | | import com.wechat.pay.contrib.apache.httpclient.util.PemUtil; |
| | | import lombok.SneakyThrows; |
| | | import org.apache.http.impl.client.CloseableHttpClient; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.io.*; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.nio.file.Files; |
| | | import java.nio.file.Paths; |
| | | import java.security.*; |
| | | import java.security.cert.Certificate; |
| | | import java.security.cert.CertificateException; |
| | | import java.security.cert.CertificateFactory; |
| | | import java.security.cert.X509Certificate; |
| | | import java.security.spec.InvalidKeySpecException; |
| | | import java.security.spec.PKCS8EncodedKeySpec; |
| | | import java.security.spec.X509EncodedKeySpec; |
| | | import java.util.Base64; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.stream.Collectors; |
| | | import java.util.stream.Stream; |
| | | |
| | | /** |
| | | * 微信支付V3 API 签名验证工具类 |
| | | */ |
| | | public class WXPaySignatureCertificateUtil { |
| | | |
| | | // 保存微信平台证书 |
| | | private static final ConcurrentHashMap<String, AutoUpdateCertificatesVerifier> verifierMap = new ConcurrentHashMap<>(); |
| | | // 缓存公钥,避免频繁IO操作 |
| | | private static PublicKey cachedPublicKey = null; |
| | | // 缓存私钥,避免频繁IO操作 |
| | | private static PrivateKey cachedPrivateKey = null; |
| | | |
| | | /** |
| | | * 获取HTTP客户端,用于微信支付API请求 |
| | | */ |
| | | public static CloseableHttpClient getWechatPayClient() throws IOException { |
| | | PrivateKey merchantPrivateKey = getPrivateKey(); |
| | | // 构建支付客户端 |
| | | return WechatPayHttpClientBuilder.create() |
| | | .withMerchant(WxV3PayConfig.Mch_ID, WxV3PayConfig.mchSerialNo, merchantPrivateKey) |
| | | .withValidator(new WechatPay2Validator(getVerifier())) |
| | | .build(); |
| | | } |
| | | |
| | | /** |
| | | * 获取自动更新的证书验证器 |
| | | */ |
| | | public static AutoUpdateCertificatesVerifier getVerifier() { |
| | | String mchSerialNo = WxV3PayConfig.mchSerialNo; |
| | | AutoUpdateCertificatesVerifier verifier = verifierMap.get(mchSerialNo); |
| | | |
| | | if (verifier == null) { |
| | | synchronized (WXPaySignatureCertificateUtil.class) { |
| | | verifier = verifierMap.get(mchSerialNo); |
| | | if (verifier == null) { |
| | | try { |
| | | PrivateKey privateKey = getPrivateKey(); |
| | | PrivateKeySigner signer = new PrivateKeySigner(mchSerialNo, privateKey); |
| | | WechatPay2Credentials credentials = new WechatPay2Credentials(WxV3PayConfig.Mch_ID, signer); |
| | | verifier = new AutoUpdateCertificatesVerifier( |
| | | credentials, WxV3PayConfig.apiV3Key.getBytes(StandardCharsets.UTF_8)); |
| | | verifierMap.put(mchSerialNo, verifier); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("初始化证书验证器失败", e); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return verifier; |
| | | } |
| | | |
| | | /** |
| | | * 使用商户私钥对数据进行签名 |
| | | * |
| | | * @param message 待签名数据 |
| | | * @return Base64编码的签名结果 |
| | | */ |
| | | public static String sign(String message) { |
| | | try { |
| | | PrivateKey privateKey = getPrivateKey(); |
| | | Signature signature = Signature.getInstance("SHA256withRSA"); |
| | | signature.initSign(privateKey); |
| | | signature.update(message.getBytes(StandardCharsets.UTF_8)); |
| | | return Base64.getEncoder().encodeToString(signature.sign()); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("签名失败", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 使用微信支付平台公钥验证签名 |
| | | * |
| | | * @param message 原始消息 |
| | | * @param signature Base64编码的签名 |
| | | * @return 验证结果 |
| | | */ |
| | | public static boolean verifySign(String message, String signature) { |
| | | try { |
| | | PublicKey publicKey = getWechatPublicKey(); |
| | | Signature sig = Signature.getInstance("SHA256withRSA"); |
| | | sig.initVerify(publicKey); |
| | | sig.update(message.getBytes(StandardCharsets.UTF_8)); |
| | | return sig.verify(Base64.getDecoder().decode(signature)); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("验签失败", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 验证微信支付通知消息的签名 |
| | | * |
| | | * @param request HTTP请求 |
| | | * @param body 请求体内容 |
| | | * @return 验证结果 |
| | | */ |
| | | public static boolean verifyNotify(HttpServletRequest request, String body) { |
| | | try { |
| | | // 获取必要的HTTP头信息 |
| | | String timestamp = request.getHeader("Wechatpay-Timestamp"); |
| | | String nonce = request.getHeader("Wechatpay-Nonce"); |
| | | String serialNo = request.getHeader("Wechatpay-Serial"); |
| | | String signature = request.getHeader("Wechatpay-Signature"); |
| | | |
| | | // 拼接验签字符串 |
| | | String message = Stream.of(timestamp, nonce, body) |
| | | .collect(Collectors.joining("\n", "", "\n")); |
| | | |
| | | // 使用自动更新的证书验证器进行验证 |
| | | return getVerifier().verify(serialNo, message.getBytes(StandardCharsets.UTF_8), signature); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("验证微信支付通知签名失败", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * APP支付签名 |
| | | */ |
| | | public static String appPaySign(String timestamp, String nonceStr, String prepayId) { |
| | | String message = Stream.of(WxV3PayConfig.APP_ID, timestamp, nonceStr, prepayId) |
| | | .collect(Collectors.joining("\n", "", "\n")); |
| | | return sign(message); |
| | | } |
| | | |
| | | /** |
| | | * JSAPI支付签名 |
| | | */ |
| | | public static String jsApiPaySign(String timestamp, String nonceStr, String prepayId) { |
| | | String message = Stream.of(WxV3PayConfig.APP_ID, timestamp, nonceStr, "prepay_id="+prepayId) |
| | | .collect(Collectors.joining("\n", "", "\n")); |
| | | return sign(message); |
| | | } |
| | | |
| | | /** |
| | | * 构建App支付参数 |
| | | */ |
| | | public static Map<String, String> buildAppPayParams(String prepayId) { |
| | | try { |
| | | String timestamp = String.valueOf(System.currentTimeMillis() / 1000); |
| | | String nonceStr = generateNonceStr(); |
| | | String sign = appPaySign(timestamp, nonceStr, prepayId); |
| | | Map<String, String> params = new HashMap<>(); |
| | | params.put("appid", WxV3PayConfig.APP_ID); |
| | | params.put("partnerid", WxV3PayConfig.Mch_ID); |
| | | params.put("prepayid", prepayId); |
| | | params.put("package", "Sign=WXPay"); |
| | | params.put("noncestr", nonceStr); |
| | | params.put("timestamp", timestamp); |
| | | params.put("sign", sign); |
| | | |
| | | return params; |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("构建App支付参数失败", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 构建JSAPI支付参数 |
| | | */ |
| | | public static Map<String, String> buildJsApiPayParams(String prepayId) { |
| | | try { |
| | | String timestamp = String.valueOf(System.currentTimeMillis() / 1000); |
| | | String nonceStr = generateNonceStr(); |
| | | String sign = jsApiPaySign(timestamp, nonceStr, prepayId); |
| | | |
| | | Map<String, String> params = new HashMap<>(); |
| | | params.put("appId", WxV3PayConfig.APP_ID); |
| | | params.put("timeStamp", timestamp); |
| | | params.put("nonceStr", nonceStr); |
| | | params.put("package", "prepay_id=" + prepayId); |
| | | params.put("signType", "RSA"); |
| | | params.put("paySign", sign); |
| | | |
| | | return params; |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("构建JSAPI支付参数失败", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 生成随机字符串 |
| | | */ |
| | | private static String generateNonceStr() { |
| | | return java.util.UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32); |
| | | } |
| | | |
| | | /** |
| | | * 获取商户私钥 |
| | | */ |
| | | public static PrivateKey getPrivateKey() { |
| | | if (cachedPrivateKey != null) { |
| | | return cachedPrivateKey; |
| | | } |
| | | |
| | | try { |
| | | String filePath = "D:\\玩湃v3参数\\apiclient_key.pem"; |
| | | String content = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8); |
| | | |
| | | String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "") |
| | | .replace("-----END PRIVATE KEY-----", "") |
| | | .replaceAll("\\s+", ""); |
| | | |
| | | KeyFactory kf = KeyFactory.getInstance("RSA"); |
| | | cachedPrivateKey = kf.generatePrivate( |
| | | new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey))); |
| | | return cachedPrivateKey; |
| | | } catch (IOException e) { |
| | | throw new RuntimeException("读取私钥文件失败", e); |
| | | } catch (NoSuchAlgorithmException e) { |
| | | throw new RuntimeException("当前Java环境不支持RSA", e); |
| | | } catch (InvalidKeySpecException e) { |
| | | throw new RuntimeException("无效的密钥格式", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取微信支付平台公钥 |
| | | */ |
| | | public static PublicKey getWechatPublicKey() { |
| | | if (cachedPublicKey != null) { |
| | | return cachedPublicKey; |
| | | } |
| | | |
| | | try { |
| | | // 使用验证器获取最新的证书 |
| | | X509Certificate certificate = getVerifier().getValidCertificate(); |
| | | cachedPublicKey = certificate.getPublicKey(); |
| | | return cachedPublicKey; |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("获取微信平台公钥失败", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 从PEM格式文件加载公钥 |
| | | */ |
| | | public static PublicKey loadPublicKeyFromFile(String filePath) { |
| | | try { |
| | | String content = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8); |
| | | |
| | | String publicKeyPEM = content |
| | | .replace("-----BEGIN PUBLIC KEY-----", "") |
| | | .replace("-----END PUBLIC KEY-----", "") |
| | | .replaceAll("\\s+", ""); |
| | | |
| | | byte[] encoded = Base64.getDecoder().decode(publicKeyPEM); |
| | | KeyFactory keyFactory = KeyFactory.getInstance("RSA"); |
| | | return keyFactory.generatePublic(new X509EncodedKeySpec(encoded)); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("加载公钥文件失败", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 从证书文件加载公钥 |
| | | */ |
| | | public static PublicKey loadPublicKeyFromCert(String filePath) { |
| | | try (FileInputStream inputStream = new FileInputStream(filePath)) { |
| | | CertificateFactory factory = CertificateFactory.getInstance("X.509"); |
| | | X509Certificate cert = (X509Certificate) factory.generateCertificate(inputStream); |
| | | return cert.getPublicKey(); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("加载证书文件失败", e); |
| | | } |
| | | } |
| | | } |
| | | //package com.dsh.activity.util.wx; |
| | | // |
| | | //import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder; |
| | | //import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier; |
| | | //import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner; |
| | | //import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials; |
| | | //import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator; |
| | | //import com.wechat.pay.contrib.apache.httpclient.util.PemUtil; |
| | | //import lombok.SneakyThrows; |
| | | //import org.apache.http.impl.client.CloseableHttpClient; |
| | | // |
| | | //import javax.servlet.http.HttpServletRequest; |
| | | //import java.io.*; |
| | | //import java.nio.charset.StandardCharsets; |
| | | //import java.nio.file.Files; |
| | | //import java.nio.file.Paths; |
| | | //import java.security.*; |
| | | //import java.security.cert.Certificate; |
| | | //import java.security.cert.CertificateException; |
| | | //import java.security.cert.CertificateFactory; |
| | | //import java.security.cert.X509Certificate; |
| | | //import java.security.spec.InvalidKeySpecException; |
| | | //import java.security.spec.PKCS8EncodedKeySpec; |
| | | //import java.security.spec.X509EncodedKeySpec; |
| | | //import java.util.Base64; |
| | | //import java.util.HashMap; |
| | | //import java.util.Map; |
| | | //import java.util.concurrent.ConcurrentHashMap; |
| | | //import java.util.stream.Collectors; |
| | | //import java.util.stream.Stream; |
| | | // |
| | | ///** |
| | | // * 微信支付V3 API 签名验证工具类 |
| | | // */ |
| | | //public class WXPaySignatureCertificateUtil { |
| | | // |
| | | // // 保存微信平台证书 |
| | | // private static final ConcurrentHashMap<String, AutoUpdateCertificatesVerifier> verifierMap = new ConcurrentHashMap<>(); |
| | | // // 缓存公钥,避免频繁IO操作 |
| | | // private static PublicKey cachedPublicKey = null; |
| | | // // 缓存私钥,避免频繁IO操作 |
| | | // private static PrivateKey cachedPrivateKey = null; |
| | | // |
| | | // /** |
| | | // * 获取HTTP客户端,用于微信支付API请求 |
| | | // */ |
| | | // public static CloseableHttpClient getWechatPayClient() throws IOException { |
| | | // PrivateKey merchantPrivateKey = getPrivateKey(); |
| | | // // 构建支付客户端 |
| | | // return WechatPayHttpClientBuilder.create() |
| | | // .withMerchant(WxV3PayConfig.Mch_ID, WxV3PayConfig.mchSerialNo, merchantPrivateKey) |
| | | // .withValidator(new WechatPay2Validator(getVerifier())) |
| | | // .build(); |
| | | // } |
| | | // |
| | | // /** |
| | | // * 获取自动更新的证书验证器 |
| | | // */ |
| | | // public static AutoUpdateCertificatesVerifier getVerifier() { |
| | | // String mchSerialNo = WxV3PayConfig.mchSerialNo; |
| | | // AutoUpdateCertificatesVerifier verifier = verifierMap.get(mchSerialNo); |
| | | // |
| | | // if (verifier == null) { |
| | | // synchronized (WXPaySignatureCertificateUtil.class) { |
| | | // verifier = verifierMap.get(mchSerialNo); |
| | | // if (verifier == null) { |
| | | // try { |
| | | // PrivateKey privateKey = getPrivateKey(); |
| | | // PrivateKeySigner signer = new PrivateKeySigner(mchSerialNo, privateKey); |
| | | // WechatPay2Credentials credentials = new WechatPay2Credentials(WxV3PayConfig.Mch_ID, signer); |
| | | // verifier = new AutoUpdateCertificatesVerifier( |
| | | // credentials, WxV3PayConfig.apiV3Key.getBytes(StandardCharsets.UTF_8)); |
| | | // verifierMap.put(mchSerialNo, verifier); |
| | | // } catch (Exception e) { |
| | | // throw new RuntimeException("初始化证书验证器失败", e); |
| | | // } |
| | | // } |
| | | // } |
| | | // } |
| | | // |
| | | // return verifier; |
| | | // } |
| | | // |
| | | // /** |
| | | // * 使用商户私钥对数据进行签名 |
| | | // * |
| | | // * @param message 待签名数据 |
| | | // * @return Base64编码的签名结果 |
| | | // */ |
| | | // public static String sign(String message) { |
| | | // try { |
| | | // PrivateKey privateKey = getPrivateKey(); |
| | | // Signature signature = Signature.getInstance("SHA256withRSA"); |
| | | // signature.initSign(privateKey); |
| | | // signature.update(message.getBytes(StandardCharsets.UTF_8)); |
| | | // return Base64.getEncoder().encodeToString(signature.sign()); |
| | | // } catch (Exception e) { |
| | | // throw new RuntimeException("签名失败", e); |
| | | // } |
| | | // } |
| | | // |
| | | // /** |
| | | // * 使用微信支付平台公钥验证签名 |
| | | // * |
| | | // * @param message 原始消息 |
| | | // * @param signature Base64编码的签名 |
| | | // * @return 验证结果 |
| | | // */ |
| | | // public static boolean verifySign(String message, String signature) { |
| | | // try { |
| | | // PublicKey publicKey = getWechatPublicKey(); |
| | | // Signature sig = Signature.getInstance("SHA256withRSA"); |
| | | // sig.initVerify(publicKey); |
| | | // sig.update(message.getBytes(StandardCharsets.UTF_8)); |
| | | // return sig.verify(Base64.getDecoder().decode(signature)); |
| | | // } catch (Exception e) { |
| | | // throw new RuntimeException("验签失败", e); |
| | | // } |
| | | // } |
| | | // |
| | | // /** |
| | | // * 验证微信支付通知消息的签名 |
| | | // * |
| | | // * @param request HTTP请求 |
| | | // * @param body 请求体内容 |
| | | // * @return 验证结果 |
| | | // */ |
| | | // public static boolean verifyNotify(HttpServletRequest request, String body) { |
| | | // try { |
| | | // // 获取必要的HTTP头信息 |
| | | // String timestamp = request.getHeader("Wechatpay-Timestamp"); |
| | | // String nonce = request.getHeader("Wechatpay-Nonce"); |
| | | // String serialNo = request.getHeader("Wechatpay-Serial"); |
| | | // String signature = request.getHeader("Wechatpay-Signature"); |
| | | // |
| | | // // 拼接验签字符串 |
| | | // String message = Stream.of(timestamp, nonce, body) |
| | | // .collect(Collectors.joining("\n", "", "\n")); |
| | | // |
| | | // // 使用自动更新的证书验证器进行验证 |
| | | // return getVerifier().verify(serialNo, message.getBytes(StandardCharsets.UTF_8), signature); |
| | | // } catch (Exception e) { |
| | | // throw new RuntimeException("验证微信支付通知签名失败", e); |
| | | // } |
| | | // } |
| | | // |
| | | // /** |
| | | // * APP支付签名 |
| | | // */ |
| | | // public static String appPaySign(String timestamp, String nonceStr, String prepayId) { |
| | | // String message = Stream.of(WxV3PayConfig.APP_ID, timestamp, nonceStr, prepayId) |
| | | // .collect(Collectors.joining("\n", "", "\n")); |
| | | // return sign(message); |
| | | // } |
| | | // |
| | | // /** |
| | | // * JSAPI支付签名 |
| | | // */ |
| | | // public static String jsApiPaySign(String timestamp, String nonceStr, String prepayId) { |
| | | // String message = Stream.of(WxV3PayConfig.APP_ID, timestamp, nonceStr, "prepay_id="+prepayId) |
| | | // .collect(Collectors.joining("\n", "", "\n")); |
| | | // return sign(message); |
| | | // } |
| | | // |
| | | // /** |
| | | // * 构建App支付参数 |
| | | // */ |
| | | // public static Map<String, String> buildAppPayParams(String prepayId) { |
| | | // try { |
| | | // String timestamp = String.valueOf(System.currentTimeMillis() / 1000); |
| | | // String nonceStr = generateNonceStr(); |
| | | // String sign = appPaySign(timestamp, nonceStr, prepayId); |
| | | // Map<String, String> params = new HashMap<>(); |
| | | // params.put("appid", WxV3PayConfig.APP_ID); |
| | | // params.put("partnerid", WxV3PayConfig.Mch_ID); |
| | | // params.put("prepayid", prepayId); |
| | | // params.put("package", "Sign=WXPay"); |
| | | // params.put("noncestr", nonceStr); |
| | | // params.put("timestamp", timestamp); |
| | | // params.put("sign", sign); |
| | | // |
| | | // return params; |
| | | // } catch (Exception e) { |
| | | // throw new RuntimeException("构建App支付参数失败", e); |
| | | // } |
| | | // } |
| | | // |
| | | // /** |
| | | // * 构建JSAPI支付参数 |
| | | // */ |
| | | // public static Map<String, String> buildJsApiPayParams(String prepayId) { |
| | | // try { |
| | | // String timestamp = String.valueOf(System.currentTimeMillis() / 1000); |
| | | // String nonceStr = generateNonceStr(); |
| | | // String sign = jsApiPaySign(timestamp, nonceStr, prepayId); |
| | | // |
| | | // Map<String, String> params = new HashMap<>(); |
| | | // params.put("appId", WxV3PayConfig.APP_ID); |
| | | // params.put("timeStamp", timestamp); |
| | | // params.put("nonceStr", nonceStr); |
| | | // params.put("package", "prepay_id=" + prepayId); |
| | | // params.put("signType", "RSA"); |
| | | // params.put("paySign", sign); |
| | | // |
| | | // return params; |
| | | // } catch (Exception e) { |
| | | // throw new RuntimeException("构建JSAPI支付参数失败", e); |
| | | // } |
| | | // } |
| | | // |
| | | // /** |
| | | // * 生成随机字符串 |
| | | // */ |
| | | // private static String generateNonceStr() { |
| | | // return java.util.UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32); |
| | | // } |
| | | // |
| | | // /** |
| | | // * 获取商户私钥 |
| | | // */ |
| | | // public static PrivateKey getPrivateKey() { |
| | | // if (cachedPrivateKey != null) { |
| | | // return cachedPrivateKey; |
| | | // } |
| | | // |
| | | // try { |
| | | // String filePath = "D:\\玩湃v3参数\\apiclient_key.pem"; |
| | | // String content = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8); |
| | | // |
| | | // String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "") |
| | | // .replace("-----END PRIVATE KEY-----", "") |
| | | // .replaceAll("\\s+", ""); |
| | | // |
| | | // KeyFactory kf = KeyFactory.getInstance("RSA"); |
| | | // cachedPrivateKey = kf.generatePrivate( |
| | | // new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey))); |
| | | // return cachedPrivateKey; |
| | | // } catch (IOException e) { |
| | | // throw new RuntimeException("读取私钥文件失败", e); |
| | | // } catch (NoSuchAlgorithmException e) { |
| | | // throw new RuntimeException("当前Java环境不支持RSA", e); |
| | | // } catch (InvalidKeySpecException e) { |
| | | // throw new RuntimeException("无效的密钥格式", e); |
| | | // } |
| | | // } |
| | | // |
| | | // /** |
| | | // * 获取微信支付平台公钥 |
| | | // */ |
| | | // public static PublicKey getWechatPublicKey() { |
| | | // if (cachedPublicKey != null) { |
| | | // return cachedPublicKey; |
| | | // } |
| | | // |
| | | // try { |
| | | // // 使用验证器获取最新的证书 |
| | | // X509Certificate certificate = getVerifier().getValidCertificate(); |
| | | // cachedPublicKey = certificate.getPublicKey(); |
| | | // return cachedPublicKey; |
| | | // } catch (Exception e) { |
| | | // throw new RuntimeException("获取微信平台公钥失败", e); |
| | | // } |
| | | // } |
| | | // |
| | | // /** |
| | | // * 从PEM格式文件加载公钥 |
| | | // */ |
| | | // public static PublicKey loadPublicKeyFromFile(String filePath) { |
| | | // try { |
| | | // String content = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8); |
| | | // |
| | | // String publicKeyPEM = content |
| | | // .replace("-----BEGIN PUBLIC KEY-----", "") |
| | | // .replace("-----END PUBLIC KEY-----", "") |
| | | // .replaceAll("\\s+", ""); |
| | | // |
| | | // byte[] encoded = Base64.getDecoder().decode(publicKeyPEM); |
| | | // KeyFactory keyFactory = KeyFactory.getInstance("RSA"); |
| | | // return keyFactory.generatePublic(new X509EncodedKeySpec(encoded)); |
| | | // } catch (Exception e) { |
| | | // throw new RuntimeException("加载公钥文件失败", e); |
| | | // } |
| | | // } |
| | | // |
| | | // /** |
| | | // * 从证书文件加载公钥 |
| | | // */ |
| | | // public static PublicKey loadPublicKeyFromCert(String filePath) { |
| | | // try (FileInputStream inputStream = new FileInputStream(filePath)) { |
| | | // CertificateFactory factory = CertificateFactory.getInstance("X.509"); |
| | | // X509Certificate cert = (X509Certificate) factory.generateCertificate(inputStream); |
| | | // return cert.getPublicKey(); |
| | | // } catch (Exception e) { |
| | | // throw new RuntimeException("加载证书文件失败", e); |
| | | // } |
| | | // } |
| | | //} |