package com.ruoyi.shop.util;
|
|
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSONObject;
|
import com.ruoyi.shop.util.dto.CertificateItem;
|
import com.ruoyi.shop.util.dto.EncryptedCertificateItem;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.codec.binary.Base64;
|
import org.apache.http.Header;
|
import org.apache.http.HttpEntity;
|
import org.apache.http.client.config.RequestConfig;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.HttpClients;
|
import org.apache.http.util.EntityUtils;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
|
import java.security.cert.X509Certificate;
|
import java.util.ArrayList;
|
import java.util.List;
|
|
/**
|
* @date 2020-03-18 15:06
|
* @description
|
*/
|
@Slf4j
|
public class Certificate {
|
|
private static final Logger logger = LoggerFactory.getLogger(Certificate.class);
|
|
/**
|
* 获取微信支付平台证书
|
*
|
* @param merchantId
|
* @param timeout
|
* @param serialNo
|
* @param mchPrivateKeyPath
|
* @param APIv3Key
|
* @param savePath
|
* @return
|
*/
|
public static List<X509Certificate> getCertByAPI(String merchantId, int timeout, String serialNo, String mchPrivateKeyPath, String wechatPubKeyPath, String APIv3Key, String savePath) {
|
String result = "";
|
//创建http请求
|
HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/certificates");
|
httpGet.addHeader("Content-Type", "application/json");
|
httpGet.addHeader("Accept", "application/json");
|
|
String authorization = SignUtils.authorization("GET", "/v3/certificates", merchantId, serialNo, "", mchPrivateKeyPath);
|
|
//设置认证信息
|
httpGet.setHeader("Authorization", authorization);
|
|
//设置请求器配置:如超时限制等
|
RequestConfig config = RequestConfig.custom().setSocketTimeout(timeout * 1000).setConnectTimeout(timeout * 1000).build();
|
httpGet.setConfig(config);
|
List<X509Certificate> x509Certs = new ArrayList<X509Certificate>();
|
try {
|
CloseableHttpClient httpClient = HttpClients.createDefault();
|
CloseableHttpResponse response = httpClient.execute(httpGet);
|
int statusCode = response.getStatusLine().getStatusCode();
|
HttpEntity httpEntity = response.getEntity();
|
result = EntityUtils.toString(httpEntity, "UTF-8");
|
if (statusCode == 200) {
|
logger.info("下载平台证书返回结果:" + result);
|
Header[] timestampHeader = response.getHeaders("Wechatpay-Timestamp");
|
Header[] nonceHeader = response.getHeaders("Wechatpay-Nonce");
|
Header[] signatureHeader = response.getHeaders("Wechatpay-Signature");
|
if (timestampHeader != null && timestampHeader.length > 0 &&
|
nonceHeader != null && nonceHeader.length > 0 &&
|
signatureHeader != null && signatureHeader.length > 0) {
|
// 验证微信支付返回签名
|
String wTimestamp = timestampHeader[0].getValue();
|
String wNonce = nonceHeader[0].getValue();
|
String wSign = signatureHeader[0].getValue();
|
|
logger.info("wTimestamp:{},wNonce:{},wSign:{}", wTimestamp, wNonce, wSign);
|
// 拼装待签名串
|
StringBuffer ss = new StringBuffer();
|
ss.append(wTimestamp).append("\n");
|
ss.append(wNonce).append("\n");
|
ss.append(result).append("\n");
|
// 验证签名
|
if (SignUtils.v3VerifyRSA(ss.toString(), Base64.decodeBase64(wSign.getBytes()), wechatPubKeyPath)) {
|
List<CertificateItem> certList = new ArrayList<CertificateItem>();
|
JSONObject json = JSONObject.parseObject(result);
|
logger.info("查询结果json字符串转证书List:" + json.get("data"));
|
JSONArray jsonArray = (JSONArray) json.get("data");
|
for (int i = 0; i < jsonArray.size(); i++) {
|
CertificateItem certificateItem = new CertificateItem();
|
EncryptedCertificateItem encryptCertificate = new EncryptedCertificateItem();
|
JSONObject bo = JSONObject.parseObject(jsonArray.get(i).toString());
|
certificateItem.setSerial_no(bo.get("serial_no").toString());
|
certificateItem.setEffective_time(bo.get("effective_time").toString());
|
certificateItem.setExpire_time(bo.get("expire_time").toString());
|
JSONObject encryptBo = JSONObject.parseObject(bo.get("encrypt_certificate").toString());
|
encryptCertificate.setAlgorithm(encryptBo.get("algorithm").toString());
|
encryptCertificate.setNonce(encryptBo.get("nonce").toString());
|
encryptCertificate.setAssociated_data(encryptBo.get("associated_data").toString());
|
encryptCertificate.setCiphertext(encryptBo.get("ciphertext").toString());
|
certificateItem.setEncrypt_certificate(encryptCertificate);
|
certList.add(certificateItem);
|
}
|
logger.info("证书List:" + certList);
|
|
/*List<PlainCertificateItem> plainList = decrypt(certList, APIv3Key);
|
if (CollectionUtils.isNotEmpty(plainList)) {
|
logger.info("平台证书开始保存");
|
x509Certs = saveCertificate(plainList, savePath);
|
}*/
|
}
|
}
|
}
|
response.close();
|
httpClient.close(); //throw
|
return x509Certs;
|
} catch (Exception e) {
|
e.printStackTrace();
|
logger.error("下载平台证书返回结果:" + e);
|
}
|
return x509Certs;
|
}
|
|
|
/*private static List<PlainCertificateItem> decrypt(List<CertificateItem> certList,CloseableHttpResponse response) throws GeneralSecurityException, IOException {
|
List<PlainCertificateItem> plainCertificateList = new ArrayList<PlainCertificateItem>();
|
AesUtil aesUtil = new AesUtil("".getBytes(StandardCharsets.UTF_8));
|
for(CertificateItem item:certList){
|
PlainCertificateItem bo = new PlainCertificateItem();
|
bo.setSerialNo(item.getSerial_no());
|
bo.setEffectiveTime(item.getEffective_time());
|
bo.setExpireTime(item.getExpire_time());
|
logger.info("平台证书密文解密");
|
bo.setPlainCertificate(aesUtil.decryptToString(item.getEncrypt_certificate().getAssociated_data().getBytes(StandardCharsets.UTF_8),
|
item.getEncrypt_certificate().getNonce().getBytes(StandardCharsets.UTF_8), item.getEncrypt_certificate().getCiphertext()));
|
logger.info("平台证书公钥明文:"+bo.getPlainCertificate());
|
plainCertificateList.add(bo);
|
}
|
return plainCertificateList;
|
}*/
|
|
|
//证书保存
|
/*private static List<X509Certificate> saveCertificate(List<PlainCertificateItem> cert) throws IOException {
|
List<X509Certificate> x509Certs = new ArrayList<X509Certificate>();
|
File file = new File("平台证书路径");
|
file.mkdirs();
|
for (PlainCertificateItem item : cert) {
|
ByteArrayInputStream inputStream = new ByteArrayInputStream(item.getPlainCertificate().getBytes(StandardCharsets.UTF_8));
|
X509Certificate x509Cert = PemUtil.loadCertificate(inputStream);
|
x509Certs.add(x509Cert);
|
String outputAbsoluteFilename = file.getAbsolutePath() + File.separator + "wechatpay_" + item.getSerialNo() + ".pem";
|
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputAbsoluteFilename), StandardCharsets.UTF_8))) {
|
writer.write(item.getPlainCertificate());
|
}
|
logger.info("输出证书文件目录:" + outputAbsoluteFilename);
|
}
|
return x509Certs;
|
}*/
|
}
|