From ecb82d98e523ffa025286ffa617096dfe18c0398 Mon Sep 17 00:00:00 2001 From: liurunyu <lry9898@163.com> Date: 星期一, 19 八月 2024 21:00:51 +0800 Subject: [PATCH] 把微信证书文件放入resources/wxCert文件夹中,读取证书文件类是pipIrrGlobal模块的WxCertUtil类。 --- pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/util/PayHelper.java | 80 ++++++++++++++++++++++++++++++++++------ 1 files changed, 68 insertions(+), 12 deletions(-) diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/util/PayHelper.java b/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/util/PayHelper.java index 6385700..c001dc1 100644 --- a/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/util/PayHelper.java +++ b/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/util/PayHelper.java @@ -5,6 +5,7 @@ import com.alibaba.fastjson2.JSONObject; import com.dy.common.webUtil.BaseResponse; import com.dy.common.webUtil.BaseResponseUtils; +import com.dy.pipIrrGlobal.cert.WxCertUtil; import com.dy.pipIrrGlobal.pojoSe.SeVirtualCard; import com.dy.pipIrrGlobal.voSe.VoOrders; import com.dy.pipIrrSell.result.SellResultCode; @@ -15,14 +16,13 @@ import com.dy.pipIrrSell.wechatpay.dto.RefundResponse; import com.dy.pipIrrSell.wechatpay.dto.ToRefund; import lombok.RequiredArgsConstructor; +import org.springframework.core.io.ResourceLoader; import org.springframework.stereotype.Component; import javax.crypto.NoSuchPaddingException; import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; import java.security.*; import java.security.cert.Certificate; import java.security.cert.CertificateException; @@ -50,7 +50,6 @@ private String resetUserSessionKeyUrl = PayInfo.resetUserSessionKeyUrl; private String notifyUrl = PayInfo.notifyUrl; private String schema = PayInfo.schema; - private String privateCertFileName = PayInfo.privateCertFileName; private String refundUrl = PayInfo.refundUrl; // 骞冲彴璇佷功鍏挜 @@ -75,9 +74,31 @@ * @param filename 绉侀挜鏂囦欢璺緞 * @return 绉侀挜瀵硅薄 * @throws IOException - */ + public PrivateKey getPrivateKey(String filename) throws IOException { String content = new String(Files.readAllBytes(Paths.get(filename)), "utf-8"); + try { + String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "") + .replace("-----END PRIVATE KEY-----", "") + .replaceAll("\\s+", ""); + KeyFactory kf = KeyFactory.getInstance("RSA"); + return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey))); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("褰撳墠Java鐜涓嶆敮鎸丷SA", e); + } catch (InvalidKeySpecException e) { + throw new RuntimeException("鏃犳晥鐨勫瘑閽ユ牸寮�"); + } + } + */ + + /** + * 鑾峰彇鍟嗘埛璇佷功绉侀挜瀵硅薄 + * @param bs 绉侀挜鏂囦欢鍐呭 + * @return 绉侀挜瀵硅薄 + * @throws IOException + */ + public PrivateKey getPrivateKey(byte[] bs) throws IOException { + String content = new String(bs, "utf-8"); try { String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "") .replace("-----END PRIVATE KEY-----", "") @@ -213,10 +234,25 @@ * @throws InvalidKeyException * @throws SignatureException * @throws IOException - */ public String sign(byte[] message, String certFileName) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, IOException { Signature sign = Signature.getInstance("SHA256withRSA"); sign.initSign(getPrivateKey(certFileName)); + sign.update(message); + return Base64.getEncoder().encodeToString(sign.sign()); + }*/ + /** + * 绛惧悕 + * @param message 琚鍚嶄俊鎭� + * @param certFileBs 绉侀挜璇佷功鏂囦欢鍐呭 + * @return signature绛惧悕鍊硷紝绛惧悕淇℃伅涓殑涓�椤癸紝鍙備笌鐢熸垚绛惧悕淇℃伅 + * @throws NoSuchAlgorithmException + * @throws InvalidKeyException + * @throws SignatureException + * @throws IOException + */ + public String sign(byte[] message, byte[] certFileBs) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, IOException { + Signature sign = Signature.getInstance("SHA256withRSA"); + sign.initSign(getPrivateKey(certFileBs)); sign.update(message); return Base64.getEncoder().encodeToString(sign.sign()); } @@ -229,10 +265,30 @@ * @return 绛惧悕淇℃伅锛孒TTP澶翠腑鐨勭鍚嶄俊鎭� * HTTP澶达細Authorization: 璁よ瘉绫诲瀷 绛惧悕淇℃伅 * 璁よ瘉绫诲瀷锛學ECHATPAY2-SHA256-RSA2048 - */ public String getToken(String method, String url, String body, String nonceStr, Long timestamp, String certFileName) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, SignatureException, InvalidKeyException, NoSuchPaddingException { String message = buildMessage_order(method, url, timestamp, nonceStr, body); String signature = sign(message.getBytes("utf-8"), certFileName); + + return "mchid=\"" + PayInfo.mchid + "\"," + + "nonce_str=\"" + nonceStr + "\"," + + "timestamp=\"" + timestamp + "\"," + + "serial_no=\"" + PayInfo.serial_no + "\"," + + "signature=\"" + signature + "\""; + } + */ + + /** + * 鑾峰彇绛惧悕淇℃伅 + * @param method + * @param url + * @param body + * @return 绛惧悕淇℃伅锛孒TTP澶翠腑鐨勭鍚嶄俊鎭� + * HTTP澶达細Authorization: 璁よ瘉绫诲瀷 绛惧悕淇℃伅 + * 璁よ瘉绫诲瀷锛學ECHATPAY2-SHA256-RSA2048 + */ + public String getToken(String method, String url, String body, String nonceStr, Long timestamp, byte[] certFileBs) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, SignatureException, InvalidKeyException, NoSuchPaddingException { + String message = buildMessage_order(method, url, timestamp, nonceStr, body); + String signature = sign(message.getBytes("utf-8"), certFileBs); return "mchid=\"" + PayInfo.mchid + "\"," + "nonce_str=\"" + nonceStr + "\"," @@ -258,13 +314,13 @@ /** * 閲嶆柊涓嬭浇璇佷功 */ - public void refreshCertificate() throws GeneralSecurityException, IOException { + public void refreshCertificate(byte[] keyPemBs) throws GeneralSecurityException, IOException, Exception { String method = "GET"; String httpUrl = "/v3/certificates"; String nonceStr = generateRandomString(); Long timestamp = System.currentTimeMillis() / 1000; - String header = PayInfo.schema + " " + getToken(method, httpUrl, "", nonceStr, timestamp, PayInfo.privateCertFileName); + String header = PayInfo.schema + " " + getToken(method, httpUrl, "", nonceStr, timestamp, keyPemBs); Map<String, String> headers = new HashMap<>(); headers.put("Authorization", header); @@ -329,10 +385,10 @@ * @throws InvalidKeyException * @throws SignatureException */ - public Boolean responseSignVerify(String wechatpaySerial, String signatureStr, String wechatpaySignature) throws GeneralSecurityException, IOException { + public Boolean responseSignVerify(String wechatpaySerial, String signatureStr, String wechatpaySignature, byte[] keyPemBs) throws GeneralSecurityException, IOException, Exception { if(CERTIFICATE_MAP.isEmpty() || !CERTIFICATE_MAP.containsKey(wechatpaySerial)) { CERTIFICATE_MAP.clear(); - refreshCertificate(); + refreshCertificate(keyPemBs); } Certificate certificate = (Certificate)CERTIFICATE_MAP.get(wechatpaySerial); if(certificate == null) { @@ -456,7 +512,7 @@ * @throws SignatureException * @throws InvalidKeyException */ - public BaseResponse<Boolean> refunds(Refund po) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, IOException, SignatureException, InvalidKeyException { + public BaseResponse<Boolean> refunds(Refund po, ResourceLoader resourceLoader) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, IOException, SignatureException, InvalidKeyException, Exception { String tradeNo = po.getTradeNo(); String refundNo = po.getRefundNo(); Integer refund = po.getRefund(); @@ -482,7 +538,7 @@ String httpUrl = "/v3/refund/domestic/refunds"; String body = JSONObject.toJSONString(refundRequest); - String header = schema + " " + getToken(method, httpUrl, body, nonceStr, timestamp, privateCertFileName); + String header = schema + " " + getToken(method, httpUrl, body, nonceStr, timestamp, WxCertUtil.getKey_pemBytes(resourceLoader)); Map<String, String> headers = new HashMap<>(); headers.put("Authorization", header); -- Gitblit v1.8.0