11package com .github .binarywang .wxpay .v3 .auth ;
22
3+ import com .fasterxml .jackson .databind .JsonNode ;
4+ import com .fasterxml .jackson .databind .ObjectMapper ;
5+ import com .github .binarywang .wxpay .v3 .Credentials ;
6+ import com .github .binarywang .wxpay .v3 .WechatPayHttpClientBuilder ;
7+ import com .github .binarywang .wxpay .v3 .util .AesUtils ;
8+ import com .github .binarywang .wxpay .v3 .util .PemUtils ;
9+ import lombok .Getter ;
10+ import lombok .RequiredArgsConstructor ;
11+ import lombok .extern .slf4j .Slf4j ;
12+ import org .apache .http .client .methods .CloseableHttpResponse ;
13+ import org .apache .http .client .methods .HttpGet ;
14+ import org .apache .http .impl .client .CloseableHttpClient ;
15+ import org .apache .http .util .EntityUtils ;
316
417import java .io .ByteArrayInputStream ;
518import java .io .IOException ;
19+ import java .nio .charset .StandardCharsets ;
620import java .security .GeneralSecurityException ;
721import java .security .cert .CertificateExpiredException ;
822import java .security .cert .CertificateNotYetValidException ;
1327import java .util .List ;
1428import java .util .concurrent .locks .ReentrantLock ;
1529
16- import com .fasterxml .jackson .databind .JsonNode ;
17- import com .fasterxml .jackson .databind .ObjectMapper ;
18- import com .github .binarywang .wxpay .v3 .Credentials ;
19- import com .github .binarywang .wxpay .v3 .WechatPayHttpClientBuilder ;
20- import com .github .binarywang .wxpay .v3 .util .AesUtils ;
21- import com .github .binarywang .wxpay .v3 .util .PemUtils ;
22- import org .apache .http .client .methods .CloseableHttpResponse ;
23- import org .apache .http .client .methods .HttpGet ;
24- import org .apache .http .impl .client .CloseableHttpClient ;
25- import org .apache .http .util .EntityUtils ;
26-
27- import org .slf4j .Logger ;
28- import org .slf4j .LoggerFactory ;
29-
3030/**
3131 * 在原有CertificatesVerifier基础上,增加自动更新证书功能
32+ *
33+ * @author doger.wang
3234 */
35+ @ Slf4j
3336public class AutoUpdateCertificatesVerifier implements Verifier {
37+ /**
38+ * 证书下载地址
39+ */
40+ private static final String CERT_DOWNLOAD_PATH = "https://api.mch.weixin.qq.com/v3/certificates" ;
3441
35- private static final Logger log = LoggerFactory .getLogger (AutoUpdateCertificatesVerifier .class );
36-
37- //证书下载地址
38- private static final String CertDownloadPath = "https://api.mch.weixin.qq.com/v3/certificates" ;
39-
40- //上次更新时间
42+ /**
43+ * 上次更新时间
44+ */
4145 private volatile Instant instant ;
4246
43- //证书更新间隔时间,单位为分钟
44- private int minutesInterval ;
47+ /**
48+ * 证书更新间隔时间,单位为分钟
49+ */
50+ private final int minutesInterval ;
4551
4652 private CertificatesVerifier verifier ;
4753
48- private Credentials credentials ;
54+ private final Credentials credentials ;
4955
50- private byte [] apiV3Key ;
56+ private final byte [] apiV3Key ;
5157
52- private ReentrantLock lock = new ReentrantLock ();
58+ private final ReentrantLock lock = new ReentrantLock ();
5359
54- //时间间隔枚举,支持一小时、六小时以及十二小时
60+ /**
61+ * 时间间隔枚举,支持一小时、六小时以及十二小时
62+ */
63+ @ Getter
64+ @ RequiredArgsConstructor
5565 public enum TimeInterval {
56- OneHour (60 ), SixHours (60 * 6 ), TwelveHours (60 * 12 );
57-
58- private int minutes ;
59-
60- TimeInterval (int minutes ) {
61- this .minutes = minutes ;
62- }
63-
64- public int getMinutes () {
65- return minutes ;
66- }
66+ /**
67+ * 一小时
68+ */
69+ OneHour (60 ),
70+ /**
71+ * 六小时
72+ */
73+ SixHours (60 * 6 ),
74+ /**
75+ * 十二小时
76+ */
77+ TwelveHours (60 * 12 );
78+
79+ private final int minutes ;
6780 }
6881
6982 public AutoUpdateCertificatesVerifier (Credentials credentials , byte [] apiV3Key ) {
@@ -103,11 +116,11 @@ public boolean verify(String serialNumber, byte[] message, String signature) {
103116
104117 private void autoUpdateCert () throws IOException , GeneralSecurityException {
105118 CloseableHttpClient httpClient = WechatPayHttpClientBuilder .create ()
106- .withCredentials (credentials )
107- .withValidator (verifier == null ? (response ) -> true : new WechatPay2Validator (verifier ))
108- .build ();
119+ .withCredentials (credentials )
120+ .withValidator (verifier == null ? (response ) -> true : new WechatPay2Validator (verifier ))
121+ .build ();
109122
110- HttpGet httpGet = new HttpGet (CertDownloadPath );
123+ HttpGet httpGet = new HttpGet (CERT_DOWNLOAD_PATH );
111124 httpGet .addHeader ("Accept" , "application/json" );
112125
113126 CloseableHttpResponse response = httpClient .execute (httpGet );
@@ -125,12 +138,10 @@ private void autoUpdateCert() throws IOException, GeneralSecurityException {
125138 }
126139 }
127140
128-
129141 /**
130142 * 反序列化证书并解密
131143 */
132- private List <X509Certificate > deserializeToCerts (byte [] apiV3Key , String body )
133- throws GeneralSecurityException , IOException {
144+ private List <X509Certificate > deserializeToCerts (byte [] apiV3Key , String body ) throws GeneralSecurityException , IOException {
134145 AesUtils decryptor = new AesUtils (apiV3Key );
135146 ObjectMapper mapper = new ObjectMapper ();
136147 JsonNode dataNode = mapper .readTree (body ).get ("data" );
@@ -140,14 +151,14 @@ private List<X509Certificate> deserializeToCerts(byte[] apiV3Key, String body)
140151 JsonNode encryptCertificateNode = dataNode .get (i ).get ("encrypt_certificate" );
141152 //解密
142153 String cert = decryptor .decryptToString (
143- encryptCertificateNode .get ("associated_data" ).toString ().replaceAll ("\" " , "" )
144- .getBytes ("utf-8" ),
145- encryptCertificateNode .get ("nonce" ).toString ().replaceAll ("\" " , "" )
146- .getBytes ("utf-8" ),
147- encryptCertificateNode .get ("ciphertext" ).toString ().replaceAll ("\" " , "" ));
154+ encryptCertificateNode .get ("associated_data" ).toString ().replaceAll ("\" " , "" )
155+ .getBytes (StandardCharsets . UTF_8 ),
156+ encryptCertificateNode .get ("nonce" ).toString ().replaceAll ("\" " , "" )
157+ .getBytes (StandardCharsets . UTF_8 ),
158+ encryptCertificateNode .get ("ciphertext" ).toString ().replaceAll ("\" " , "" ));
148159
149160 X509Certificate x509Cert = PemUtils
150- .loadCertificate (new ByteArrayInputStream (cert .getBytes ("utf-8" )));
161+ .loadCertificate (new ByteArrayInputStream (cert .getBytes (StandardCharsets . UTF_8 )));
151162 try {
152163 x509Cert .checkValidity ();
153164 } catch (CertificateExpiredException | CertificateNotYetValidException e ) {
@@ -156,6 +167,7 @@ private List<X509Certificate> deserializeToCerts(byte[] apiV3Key, String body)
156167 newCertList .add (x509Cert );
157168 }
158169 }
170+
159171 return newCertList ;
160172 }
161173}
0 commit comments