From 73b65194e1ba91dd0003ed2a11340d9c1393573b Mon Sep 17 00:00:00 2001
From: KKSU <15274802129@163.com>
Date: Wed, 17 Jan 2024 15:28:10 +0800
Subject: [PATCH] fapiao

---
 src/test/java/cc/mrbird/febs/ProfitTest.java                           |   69 ++++++++++++++++++++++-
 src/main/java/cc/mrbird/febs/pay/util/JCEUtil.java                     |   70 +++++++++++++++++++++++
 src/main/java/cc/mrbird/febs/pay/service/impl/WxFaPiaoServiceImpl.java |   33 +++++------
 3 files changed, 151 insertions(+), 21 deletions(-)

diff --git a/src/main/java/cc/mrbird/febs/pay/service/impl/WxFaPiaoServiceImpl.java b/src/main/java/cc/mrbird/febs/pay/service/impl/WxFaPiaoServiceImpl.java
index ec935be..577b465 100644
--- a/src/main/java/cc/mrbird/febs/pay/service/impl/WxFaPiaoServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/pay/service/impl/WxFaPiaoServiceImpl.java
@@ -10,6 +10,7 @@
 import cc.mrbird.febs.pay.model.FPEncryptCertificate;
 import cc.mrbird.febs.pay.model.HeaderDto;
 import cc.mrbird.febs.pay.service.WxFaPiaoService;
+import cc.mrbird.febs.pay.util.JCEUtil;
 import cc.mrbird.febs.pay.util.RandomStringGenerator;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONObject;
@@ -29,6 +30,8 @@
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import okhttp3.HttpUrl;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.methods.CloseableHttpResponse;
@@ -273,12 +276,8 @@
                     log.info("微信电子发票回调接口....resource解密:"+decryptToString);
 
                     JSONObject parseObj = JSONUtil.parseObj(decryptToString);
-
                     log.info("微信电子发票回调接口....resource解密-JSONObject:"+parseObj);
-
-                    String mchid = String.valueOf(parseObj.get("mchid"));
                     String fapiao_apply_id = String.valueOf(parseObj.get("fapiao_apply_id"));
-                    String apply_time = String.valueOf(parseObj.get("apply_time"));
                     MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectByOrderNo(fapiao_apply_id);
                     if(ObjectUtil.isNotEmpty(mallOrderInfo)){
                         //省略查询订单
@@ -333,8 +332,8 @@
      * 获取平台证书
      */
     public X509Certificate getCertificates() throws IOException, NoSuchAlgorithmException, SignatureException, InvalidKeyException, ParseException {
+        JCEUtil.removeCryptographyRestrictions();
         SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
-        CloseableHttpClient httpClient = HttpClients.createDefault();
 
         PrivateKey privateKey = this.getPrivateKeyV3();
         String baseUrl = "https://api.mch.weixin.qq.com";
@@ -351,20 +350,23 @@
         } catch (NoSuchAlgorithmException e) {
             e.printStackTrace();
         }
+        HttpClient httpClient = new HttpClient();
         //请求URL
-        HttpGet httpGet = new HttpGet(baseUrl+canonicalUrl);
-        httpGet.setHeader("Accept", "application/json");
-        //生成签名
-        httpGet.setHeader("Authorization ", "WECHATPAY2-SHA256-RSA2048"+postStr);
-        httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36");
+        GetMethod method = new GetMethod(baseUrl+canonicalUrl);
+        method.setRequestHeader("Accept", "application/json");
+        method.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36");
+        method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
+//            method.setRequestHeader("Connection", "keep-alive");
+        method.setRequestHeader("Authorization", "WECHATPAY2-SHA256-RSA2048 "+postStr);
+        int statusCode = httpClient.executeMethod(method);
         //完成签名并执行请求
-        CloseableHttpResponse response = httpClient.execute(httpGet);
         X509Certificate x509Certificate = null;
         try {
-            int statusCode = response.getStatusLine().getStatusCode();
             if (statusCode == 200) { //处理成功
 //                System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
-                FPCertificateVo certificateVo = com.alibaba.fastjson.JSONObject.parseObject(EntityUtils.toString(response.getEntity()), FPCertificateVo.class);
+
+                String responseBodyAsString = method.getResponseBodyAsString();
+                FPCertificateVo certificateVo = com.alibaba.fastjson.JSONObject.parseObject(responseBodyAsString, FPCertificateVo.class);
                 for (FPCertificates certificates : certificateVo.getData()) {
                     if (format.parse(certificates.getEffective_time()).before(new Date())
                             && format.parse(certificates.getExpire_time()).after(new Date())) {
@@ -385,18 +387,13 @@
                 }
                 return x509Certificate;
             } else if (statusCode == 204) { //处理成功,无返回Body
-                System.out.println("success");
                 return x509Certificate;
             } else {
-                System.out.println("failed,resp code = " + statusCode + ",return body = " + EntityUtils.toString(response.getEntity()));
                 return x509Certificate;
             }
         } catch (GeneralSecurityException | ParseException e) {
             e.printStackTrace();
             return null;
-        } finally {
-            response.close();
-            httpClient.close();
         }
     }
 
diff --git a/src/main/java/cc/mrbird/febs/pay/util/JCEUtil.java b/src/main/java/cc/mrbird/febs/pay/util/JCEUtil.java
new file mode 100644
index 0000000..1bb2695
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/pay/util/JCEUtil.java
@@ -0,0 +1,70 @@
+package cc.mrbird.febs.pay.util;
+
+import javax.crypto.Cipher;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.security.NoSuchAlgorithmException;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.Map;
+
+/**
+ * 解决因jdk版本问题不支持aes256加密问题(Illegal key size or default parameters)
+ */
+public class JCEUtil {
+    public static void removeCryptographyRestrictions() {
+        if (!isRestrictedCryptography()) {
+            System.out.println("Cryptography restrictions removal not needed");
+            return;
+        }
+        try {
+            /*
+             * Do the following, but with reflection to bypass access checks:
+             *
+             * JceSecurity.isRestricted = false;
+             * JceSecurity.defaultPolicy.perms.clear();
+             * JceSecurity.defaultPolicy.add(CryptoAllPermission.INSTANCE);
+             */
+            final Class<?> jceSecurity = Class.forName("javax.crypto.JceSecurity");
+            final Class<?> cryptoPermissions = Class.forName("javax.crypto.CryptoPermissions");
+            final Class<?> cryptoAllPermission = Class.forName("javax.crypto.CryptoAllPermission");
+
+            final Field isRestrictedField = jceSecurity.getDeclaredField("isRestricted");
+            isRestrictedField.setAccessible(true);
+            //去除isRestricted的final限制
+            final Field modifiersField = Field.class.getDeclaredField("modifiers");
+            modifiersField.setAccessible(true);
+            modifiersField.setInt(isRestrictedField, isRestrictedField.getModifiers() & ~Modifier.FINAL);
+            isRestrictedField.set(null, false);
+
+            final Field defaultPolicyField = jceSecurity.getDeclaredField("defaultPolicy");
+            defaultPolicyField.setAccessible(true);
+            final PermissionCollection defaultPolicy = (PermissionCollection) defaultPolicyField.get(null);
+
+            final Field perms = cryptoPermissions.getDeclaredField("perms");
+            perms.setAccessible(true);
+            ((Map<?, ?>) perms.get(defaultPolicy)).clear();
+
+            final Field instance = cryptoAllPermission.getDeclaredField("INSTANCE");
+            instance.setAccessible(true);
+            defaultPolicy.add((Permission) instance.get(null));
+
+        } catch (final Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static boolean isRestrictedCryptography() {
+        // This matches Oracle Java 7 and 8, but not Java 9 or OpenJDK.
+        final String name = System.getProperty("java.runtime.name");
+        final String ver = System.getProperty("java.version");
+        return name != null && name.equals("Java(TM) SE Runtime Environment")
+                && ver != null && (ver.startsWith("1.7") || ver.startsWith("1.8"));
+    }
+
+    public static void main(String[] args) throws NoSuchAlgorithmException {
+//        removeCryptographyRestrictions();
+        long length = Cipher.getMaxAllowedKeyLength("AES/CBC/PKCS5Padding");
+        System.out.println(length);
+    }
+}
diff --git a/src/test/java/cc/mrbird/febs/ProfitTest.java b/src/test/java/cc/mrbird/febs/ProfitTest.java
index a9eacb1..554e4dd 100644
--- a/src/test/java/cc/mrbird/febs/ProfitTest.java
+++ b/src/test/java/cc/mrbird/febs/ProfitTest.java
@@ -16,6 +16,7 @@
 import cc.mrbird.febs.pay.model.*;
 import cc.mrbird.febs.pay.service.IXcxPayService;
 import cc.mrbird.febs.pay.service.WxFaPiaoService;
+import cc.mrbird.febs.pay.util.JCEUtil;
 import cc.mrbird.febs.pay.util.WechatConfigure;
 import cc.mrbird.febs.rabbit.consumer.AgentConsumer;
 import cn.hutool.core.collection.CollUtil;
@@ -28,6 +29,7 @@
 import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
 import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
 import com.wechat.pay.contrib.apache.httpclient.notification.NotificationHandler;
+import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
 import okhttp3.HttpUrl;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.httpclient.HttpClient;
@@ -58,9 +60,11 @@
 import java.net.URLConnection;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
-import java.security.KeyPair;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
+import java.security.*;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.*;
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
@@ -278,6 +282,65 @@
 
     }
 
+    @Test
+    public void rankProfit2_01() throws IOException, ParseException, GeneralSecurityException {//获取平台证书
+        JCEUtil.removeCryptographyRestrictions();
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+        PrivateKey privateKey = wxFaPiaoService.getPrivateKeyV3();
+        String baseUrl = "https://api.mch.weixin.qq.com";
+        String canonicalUrl = "/v3/certificates";
+        String postStr = null;
+        try {
+            postStr = wxFaPiaoService.createAuthorization(
+                    "GET",
+                    baseUrl+canonicalUrl,
+                    "",
+                    privateKey
+
+            );
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        HttpClient httpClient = new HttpClient();
+        try {
+            GetMethod method = new GetMethod(baseUrl+canonicalUrl);
+            method.setRequestHeader("Accept", "application/json");
+            method.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36");
+            method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
+//            method.setRequestHeader("Connection", "keep-alive");
+            method.setRequestHeader("Authorization", "WECHATPAY2-SHA256-RSA2048 "+postStr);
+            int i = httpClient.executeMethod(method);
+            System.out.println(i);
+            System.out.println(method);
+            String responseBodyAsString = method.getResponseBodyAsString();
+            cn.hutool.json.JSONObject maps = JSONUtil.parseObj(responseBodyAsString);
+            System.out.println(maps);
+
+            FPCertificateVo certificateVo = com.alibaba.fastjson.JSONObject.parseObject(responseBodyAsString, FPCertificateVo.class);
+            for (FPCertificates certificates : certificateVo.getData()) {
+                if (format.parse(certificates.getEffective_time()).before(new Date())
+                        && format.parse(certificates.getExpire_time()).after(new Date())) {
+                    FPEncryptCertificate encrypt_certificate = certificates.getEncrypt_certificate();
+                    //解密
+                    AesUtil aesUtil = new AesUtil("daL341aN5orDt13puXadsAf2rpuX12v3".getBytes("utf-8"));
+                    String pulicKey = aesUtil.decryptToString(
+                            encrypt_certificate.getAssociated_data().getBytes("utf-8"),
+                            encrypt_certificate.getNonce().getBytes("utf-8"),
+                            encrypt_certificate.getCiphertext());
+                    //获取平台证书
+                    final CertificateFactory cf = CertificateFactory.getInstance("X509");
+
+                    ByteArrayInputStream inputStream = new ByteArrayInputStream(pulicKey.getBytes(StandardCharsets.UTF_8));
+
+                    X509Certificate x509Certificate = (X509Certificate) cf.generateCertificate(inputStream);
+                    System.out.println(x509Certificate);
+                }
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
 
     @Autowired
     private MallOrderInfoMapper mallOrderInfoMapper;

--
Gitblit v1.9.1