src/main/java/cc/mrbird/febs/pay/service/impl/WxFaPiaoServiceImpl.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/pay/util/JCEUtil.java | ●●●●● patch | view | raw | blame | history | |
src/test/java/cc/mrbird/febs/ProfitTest.java | ●●●●● patch | view | raw | blame | history |
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(); } } src/main/java/cc/mrbird/febs/pay/util/JCEUtil.java
New file @@ -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); } } 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;