19
19
import java .io .*;
20
20
import java .net .URL ;
21
21
import java .nio .charset .StandardCharsets ;
22
- import java .nio .file .Files ;
23
22
import java .security .KeyStore ;
24
23
import java .security .PrivateKey ;
24
+ import java .security .cert .Certificate ;
25
25
import java .security .cert .X509Certificate ;
26
26
import java .util .Base64 ;
27
27
import java .util .Optional ;
@@ -263,17 +263,31 @@ public CloseableHttpClient initApiV3HttpClient() throws WxPayException {
263
263
throw new WxPayException ("请确保apiV3Key值已设置" );
264
264
}
265
265
266
- if (StringUtils .isNotBlank (this .getPrivateKeyString ())){
267
- this .setPrivateKeyString (Base64 .getEncoder ().encodeToString (this .getPrivateKeyString ().getBytes ()));
266
+ // 尝试从p12证书中加载私钥和证书
267
+ PrivateKey merchantPrivateKey = null ;
268
+ X509Certificate certificate = null ;
269
+ Object [] objects = this .p12ToPem ();
270
+ if (objects != null ) {
271
+ merchantPrivateKey = (PrivateKey ) objects [0 ];
272
+ certificate = (X509Certificate ) objects [1 ];
268
273
}
269
- InputStream keyInputStream = this .loadConfigInputStream (this .getPrivateKeyString (), this .getPrivateKeyPath (),
270
- this .privateKeyContent , "privateKeyPath" );
271
274
try {
272
- PrivateKey merchantPrivateKey = PemUtils .loadPrivateKey (keyInputStream );
273
- if (StringUtils .isBlank (this .getCertSerialNo ())) {
275
+ if (merchantPrivateKey == null ) {
276
+ if (StringUtils .isNotBlank (this .getPrivateKeyString ())) {
277
+ this .setPrivateKeyString (Base64 .getEncoder ().encodeToString (this .getPrivateKeyString ().getBytes ()));
278
+ }
279
+ InputStream keyInputStream = this .loadConfigInputStream (this .getPrivateKeyString (), this .getPrivateKeyPath (),
280
+ this .privateKeyContent , "privateKeyPath" );
281
+ merchantPrivateKey = PemUtils .loadPrivateKey (keyInputStream );
282
+
283
+ }
284
+ if (certificate == null ) {
274
285
InputStream certInputStream = this .loadConfigInputStream (this .getPrivateCertString (), this .getPrivateCertPath (),
275
286
this .privateCertContent , "privateCertPath" );
276
- X509Certificate certificate = PemUtils .loadCertificate (certInputStream );
287
+ certificate = PemUtils .loadCertificate (certInputStream );
288
+ }
289
+
290
+ if (StringUtils .isBlank (this .getCertSerialNo ())) {
277
291
this .certSerialNo = certificate .getSerialNumber ().toString (16 ).toUpperCase ();
278
292
}
279
293
//构造Http Proxy正向代理
@@ -391,6 +405,54 @@ private InputStream loadConfigInputStream(String configPath) throws WxPayExcepti
391
405
throw new WxPayException (fileHasProblemMsg , e );
392
406
}
393
407
}
408
+ }
409
+
410
+ /**
411
+ * 从配置路径 加载p12证书文件流
412
+ *
413
+ * @return 文件流
414
+ */
415
+ private InputStream loadP12InputStream () {
416
+ try (InputStream inputStream = this .loadConfigInputStream (this .keyString , this .getKeyPath (),
417
+ this .keyContent , "p12证书" );) {
418
+ return inputStream ;
419
+ } catch (Exception e ) {
420
+ return null ;
421
+ }
422
+ }
423
+
424
+ /**
425
+ * 分解p12证书文件
426
+ *
427
+ * @return
428
+ */
429
+ private Object [] p12ToPem () {
430
+ InputStream inputStream = this .loadP12InputStream ();
431
+ if (inputStream == null ) {
432
+ return null ;
433
+ }
434
+ String key = getMchId ();
435
+ if (StringUtils .isBlank (key )) {
436
+ return null ;
437
+ }
438
+ // 分解p12证书文件
439
+ PrivateKey privateKey = null ;
440
+ X509Certificate x509Certificate = null ;
441
+ try {
442
+ KeyStore keyStore = KeyStore .getInstance ("PKCS12" );
443
+ keyStore .load (inputStream , key .toCharArray ());
444
+
445
+ String alias = keyStore .aliases ().nextElement ();
446
+ privateKey = (PrivateKey ) keyStore .getKey (alias , key .toCharArray ());
447
+
448
+ Certificate certificate = keyStore .getCertificate (alias );
449
+ x509Certificate = (X509Certificate ) certificate ;
450
+ return new Object []{privateKey , x509Certificate };
451
+ } catch (Exception ignored ) {
452
+
453
+ }
454
+ return null ;
455
+
394
456
395
457
}
396
458
}
0 commit comments