66import com .github .binarywang .wxpay .v3 .WxPayV3HttpClientBuilder ;
77import com .github .binarywang .wxpay .v3 .auth .*;
88import com .github .binarywang .wxpay .v3 .util .PemUtils ;
9- import lombok .Data ;
10- import lombok .EqualsAndHashCode ;
11- import lombok .SneakyThrows ;
12- import lombok .ToString ;
13- import lombok .extern .slf4j .Slf4j ;
14- import org .apache .commons .lang3 .RegExUtils ;
15- import org .apache .commons .lang3 .StringUtils ;
16- import org .apache .http .impl .client .CloseableHttpClient ;
17- import org .apache .http .ssl .SSLContexts ;
18-
19- import javax .net .ssl .SSLContext ;
209import java .io .*;
2110import java .net .URL ;
2211import java .nio .charset .StandardCharsets ;
2312import java .security .KeyStore ;
2413import java .security .PrivateKey ;
14+ import java .security .PublicKey ;
2515import java .security .cert .Certificate ;
2616import java .security .cert .X509Certificate ;
2717import java .util .Base64 ;
2818import java .util .Optional ;
19+ import javax .net .ssl .SSLContext ;
20+ import lombok .Data ;
21+ import lombok .EqualsAndHashCode ;
22+ import lombok .SneakyThrows ;
23+ import lombok .ToString ;
24+ import lombok .extern .slf4j .Slf4j ;
25+ import org .apache .commons .lang3 .RegExUtils ;
26+ import org .apache .commons .lang3 .StringUtils ;
27+ import org .apache .http .impl .client .CloseableHttpClient ;
28+ import org .apache .http .ssl .SSLContexts ;
2929
3030/**
3131 * 微信支付配置
@@ -138,6 +138,25 @@ public class WxPayConfig {
138138 */
139139 private byte [] privateCertContent ;
140140
141+ /**
142+ * 公钥ID
143+ */
144+ private String publicKeyId ;
145+
146+ /**
147+ * pub_key.pem证书base64编码
148+ */
149+ private String publicKeyString ;
150+
151+ /**
152+ * pub_key.pem证书文件的绝对路径或者以classpath:开头的类路径.
153+ */
154+ private String publicKeyPath ;
155+
156+ /**
157+ * pub_key.pem证书文件内容的字节数组.
158+ */
159+ private byte [] publicKeyContent ;
141160 /**
142161 * apiV3 秘钥值.
143162 */
@@ -241,7 +260,7 @@ public SSLContext initSSLContext() throws WxPayException {
241260 }
242261
243262 try (InputStream inputStream = this .loadConfigInputStream (this .keyString , this .getKeyPath (),
244- this .keyContent , "p12证书" ); ) {
263+ this .keyContent , "p12证书" )) {
245264 KeyStore keystore = KeyStore .getInstance ("PKCS12" );
246265 char [] partnerId2charArray = this .getMchId ().toCharArray ();
247266 keystore .load (inputStream , partnerId2charArray );
@@ -284,7 +303,6 @@ public CloseableHttpClient initApiV3HttpClient() throws WxPayException {
284303 this .privateKeyContent , "privateKeyPath" )) {
285304 merchantPrivateKey = PemUtils .loadPrivateKey (keyInputStream );
286305 }
287-
288306 }
289307 if (certificate == null && StringUtils .isBlank (this .getCertSerialNo ())) {
290308 try (InputStream certInputStream = this .loadConfigInputStream (this .getPrivateCertString (), this .getPrivateCertPath (),
@@ -293,13 +311,28 @@ public CloseableHttpClient initApiV3HttpClient() throws WxPayException {
293311 }
294312 this .certSerialNo = certificate .getSerialNumber ().toString (16 ).toUpperCase ();
295313 }
314+ PublicKey publicKey = null ;
315+ if (this .getPublicKeyString () != null || this .getPublicKeyPath () != null || this .publicKeyContent != null ) {
316+ try (InputStream pubInputStream =
317+ this .loadConfigInputStream (this .getPublicKeyString (), this .getPublicKeyPath (),
318+ this .publicKeyContent , "publicKeyPath" )) {
319+ publicKey = PemUtils .loadPublicKey (pubInputStream );
320+ }
321+ }
296322
297323 //构造Http Proxy正向代理
298324 WxPayHttpProxy wxPayHttpProxy = getWxPayHttpProxy ();
299325
300- AutoUpdateCertificatesVerifier certificatesVerifier = new AutoUpdateCertificatesVerifier (
301- new WxPayCredentials (mchId , new PrivateKeySigner (certSerialNo , merchantPrivateKey )),
302- this .getApiV3Key ().getBytes (StandardCharsets .UTF_8 ), this .getCertAutoUpdateTime (), this .getPayBaseUrl (), wxPayHttpProxy );
326+ Verifier certificatesVerifier ;
327+ if (publicKey == null ) {
328+ certificatesVerifier =
329+ new AutoUpdateCertificatesVerifier (
330+ new WxPayCredentials (mchId , new PrivateKeySigner (certSerialNo , merchantPrivateKey )),
331+ this .getApiV3Key ().getBytes (StandardCharsets .UTF_8 ), this .getCertAutoUpdateTime (),
332+ this .getPayBaseUrl (), wxPayHttpProxy );
333+ } else {
334+ certificatesVerifier = new PublicCertificateVerifier (publicKey , publicKeyId );
335+ }
303336
304337 WxPayV3HttpClientBuilder wxPayV3HttpClientBuilder = WxPayV3HttpClientBuilder .create ()
305338 .withMerchant (mchId , certSerialNo , merchantPrivateKey )
@@ -422,7 +455,7 @@ private Object[] p12ToPem() {
422455
423456 // 分解p12证书文件
424457 try (InputStream inputStream = this .loadConfigInputStream (this .keyString , this .getKeyPath (),
425- this .keyContent , "p12证书" ); ) {
458+ this .keyContent , "p12证书" )) {
426459 KeyStore keyStore = KeyStore .getInstance ("PKCS12" );
427460 keyStore .load (inputStream , key .toCharArray ());
428461
0 commit comments