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