@@ -55,6 +55,7 @@ public class WxPayConfig {
5555 private static final String DEFAULT_PAY_BASE_URL = "https://api.mch.weixin.qq.com" ;
5656 private static final String PROBLEM_MSG = "证书文件【%s】有问题,请核实!" ;
5757 private static final String NOT_FOUND_MSG = "证书文件【%s】不存在,请核实!" ;
58+ private static final String CERT_NAME_P12 = "p12证书" ;
5859
5960 /**
6061 * 微信支付接口请求地址域名部分.
@@ -306,7 +307,7 @@ public SSLContext initSSLContext() throws WxPayException {
306307 }
307308
308309 try (InputStream inputStream = this .loadConfigInputStream (this .keyString , this .getKeyPath (),
309- this .keyContent , "p12证书" )) {
310+ this .keyContent , CERT_NAME_P12 )) {
310311 KeyStore keystore = KeyStore .getInstance ("PKCS12" );
311312 char [] partnerId2charArray = this .getMchId ().toCharArray ();
312313 keystore .load (inputStream , partnerId2charArray );
@@ -437,12 +438,34 @@ private InputStream loadConfigInputStream(String configString, String configPath
437438
438439 if (StringUtils .isNotEmpty (configString )) {
439440 // 判断是否为PEM格式的字符串(包含-----BEGIN和-----END标记)
440- if (configString . contains ( "-----BEGIN" ) && configString . contains ( "-----END" )) {
441+ if (isPemFormat ( configString )) {
441442 // PEM格式直接转为字节流,让PemUtils处理
442443 configContent = configString .getBytes (StandardCharsets .UTF_8 );
443444 } else {
444- // 纯Base64格式,需要先解码
445- configContent = Base64 .getDecoder ().decode (configString );
445+ // 尝试Base64解码
446+ try {
447+ byte [] decoded = Base64 .getDecoder ().decode (configString );
448+ // 检查解码后的内容是否为PEM格式(即用户传入的是base64编码的完整PEM文件)
449+ String decodedString = new String (decoded , StandardCharsets .UTF_8 );
450+ if (isPemFormat (decodedString )) {
451+ // 解码后是PEM格式,使用解码后的内容
452+ configContent = decoded ;
453+ } else {
454+ // 解码后不是PEM格式,可能是:
455+ // 1. p12证书的二进制内容 - 应该返回解码后的二进制数据
456+ // 2. 私钥/公钥的纯base64内容(不含PEM头尾) - 应该返回原始字符串,让PemUtils处理
457+ // 通过certName区分:p12证书使用解码后的数据,其他情况返回原始字符串
458+ if (CERT_NAME_P12 .equals (certName )) {
459+ configContent = decoded ;
460+ } else {
461+ // 对于私钥/公钥/证书,返回原始字符串字节,让PemUtils处理base64解码
462+ configContent = configString .getBytes (StandardCharsets .UTF_8 );
463+ }
464+ }
465+ } catch (IllegalArgumentException e ) {
466+ // Base64解码失败,可能是格式不正确,抛出异常
467+ throw new WxPayException (String .format ("【%s】的Base64格式不正确" , certName ), e );
468+ }
446469 }
447470 return new ByteArrayInputStream (configContent );
448471 }
@@ -454,6 +477,16 @@ private InputStream loadConfigInputStream(String configString, String configPath
454477 return this .loadConfigInputStream (configPath );
455478 }
456479
480+ /**
481+ * 判断字符串是否为PEM格式(包含-----BEGIN和-----END标记)
482+ *
483+ * @param content 要检查的字符串
484+ * @return 是否为PEM格式
485+ */
486+ private boolean isPemFormat (String content ) {
487+ return content != null && content .contains ("-----BEGIN" ) && content .contains ("-----END" );
488+ }
489+
457490
458491 /**
459492 * 从配置路径 加载配置 信息(支持 classpath、本地路径、网络url)
@@ -523,7 +556,7 @@ private Object[] p12ToPem() {
523556
524557 // 分解p12证书文件
525558 try (InputStream inputStream = this .loadConfigInputStream (this .keyString , this .getKeyPath (),
526- this .keyContent , "p12证书" )) {
559+ this .keyContent , CERT_NAME_P12 )) {
527560 KeyStore keyStore = KeyStore .getInstance ("PKCS12" );
528561 keyStore .load (inputStream , key .toCharArray ());
529562
0 commit comments