在微信开发时,消息接口时,涉及到消息加密,抛出了 java.security.InvalidKeyException: Illegal key size 的异常,异常堆栈如下:

按照网上的解决方案,都是要求替换JDK目录下两个jar包,

对于一些生产系统 这种方式就不是很方便了,经过探索,发现一种方案,通过反射机制来解决

查看JDK源码,Cihper.checkCryptoPermcheckCryptoPerm,代码如下

    private void checkCryptoPerm(CipherSpi var1, Key var2) throws InvalidKeyException {
if (this.cryptoPerm != CryptoAllPermission.INSTANCE) {
AlgorithmParameterSpec var3;
try {
var3 = this.getAlgorithmParameterSpec(var1.engineGetParameters());
} catch (InvalidParameterSpecException var5) {
throw new InvalidKeyException("Unsupported default algorithm parameters");
} if (!this.passCryptoPermCheck(var1, var2, var3)) {
throw new InvalidKeyException("Illegal key size or default parameters");
}
}
}

其中主要的就是 this.cryptoPerm != CryptoAllPermission.INSTANCE ,找到cryptoPerm初始化的位置,有一个方法

    private void initCryptoPermission() throws NoSuchAlgorithmException {
if (!JceSecurity.isRestricted()) {
this.cryptoPerm = CryptoAllPermission.INSTANCE;
this.exmech = null;
} else {
this.cryptoPerm = getConfiguredPermission(this.transformation);
String var1 = this.cryptoPerm.getExemptionMechanism();
if (var1 != null) {
this.exmech = ExemptionMechanism.getInstance(var1);
} }
}

意思是,如果 JceSecurity.isRestricted() 返回true,则使用CryptoAllPermission.INSTANCE实例 否则需要进行key的校验,因此修改这个方法就行了

isRestricted方法的内容如下:

final class JceSecurity {

private static final boolean isRestricted; //默认情况下为true
static boolean isRestricted() {
return isRestricted;
} }

isRestricted这是一个private static final变量,可通过反射的方式修改

反射修改private field值的方法是

Field field = Class.forName("类名").getDeclaredField("属性名");
field.setAccessible(true);
field.set(null,值); // 如果是static,第一个参数填null,否则填实例对象

由于这个属性的final的,需要对Field.class再反射一次,从modifiers中去掉final属性:

Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

完整的代码:

//解决微信开发时,InvalidKeyException:illegal Key Size的问题

//反射获取isRestrictedfield
Field field = Class.forName("javax.crypto.JceSecurity").getDeclaredField("isRestricted");

//这个field是 private static final的,需要找到这个field的modifiers,将final去掉,才能修改
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

//修改field
field.setAccessible(true);
field.set(null,false);

执行完整的代码后,加密/解密正常,用微信企业号默认的SDK,测试加密通过

import com.yomahub.liteflow.example.utils.WXBizMsgCrypt;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier; public class Test {
public static void main(String[] args) throws Exception { //解决微信开发时,InvalidKeyException:illegal Key Size的问题 //反射获取isRestrictedfield
Field field = Class.forName("javax.crypto.JceSecurity").getDeclaredField("isRestricted"); //这个field是 private static final的,需要找到这个field的modifiers,将final去掉,才能修改
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); //修改field
field.setAccessible(true);
field.set(null,false); String sToken = "QDG6eK";
String sCorpID = "wx5823bf96d3bd56c7";
String sEncodingAESKey = "jWmYm7qr5nMoAUwZRjGtBxmz3KA1tkAj3ykkR6q2B2C"; WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID); String sRespData = "<xml><ToUserName><![CDATA[mycreate]]></ToUserName><FromUserName><![CDATA[wx5823bf96d3bd56c7]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId><AgentID>128</AgentID></xml>";
String sReqTimeStamp = "1409659813"; String sReqNonce = "1372623149";
String result = wxcpt.EncryptMsg(sRespData,sReqTimeStamp,sReqNonce); System.out.println(result);
}
}

反射解决微信开发加解密illegal key size,不需要修改JDK jar包的更多相关文章

  1. aes加解密 Illegal key size

    做aes加密时,发生一个奇怪的错误,在本地环境是好的,发布到测试环境就出问题, java.security.InvalidKeyException: Illegal key size 想到本地环境之前 ...

  2. java 加密 解密 Illegal key size

    java.security.InvalidKeyException: Illegal key size   今天遇到一个奇怪的问题. 自己做的加签验签功能已经没有问题了,本地测试通过,同事放到服务器上 ...

  3. AES的256位密钥加解密报 java.security.InvalidKeyException: Illegal key size or default parameters 异常的处理及处理工具

    一.出现的现象为了数据代码在传输过程中的安全,很多时候我们都会将要传输的数据进行加密,然后等对方拿到后再解密使用.我们在使用AES加解密的时候,在遇到128位密钥加解密的时候,没有进行什么特殊处理:然 ...

  4. 微信 AES 解密报错 Illegal key size 三种解决办法

    微信 AES 解密报错 Illegal key size Java 环境 java version "1.8.0_151" Java(TM) SE Runtime Environm ...

  5. AES加解密异常java.security.InvalidKeyException: Illegal key size

    AES加解密异常 Java后台AES解密,抛出异常如下:java.security.InvalidKeyException: Illegal key size Illegal key size or ...

  6. 使用delphi+intraweb进行微信开发4—微信消息加解密

    示例代码已经放出!请移步使用delphi+intraweb进行微信开发1~4代码示例进行下载,虽为示例代码但是是从我项目中移出来的,封装很完备适于自行扩展和修改. 在上一讲当中我做了个简单的微信文本消 ...

  7. Java企业微信开发_Exception_02_java.security.InvalidKeyException: Illegal key size

    今天换了重新装了一个jdk,然后运行昨天还好好的企业微信工程,结果启动的时候就给我报了这么个错: java.security.InvalidKeyException: Illegal key size ...

  8. Java 解密错误InvalidKeyException: Illegal key size解决方法

    做解密操作,出现如下错误 java.security.InvalidKeyException: Illegal key size // 设置解密模式为AES的CBC模式 Cipher cipher = ...

  9. 微信退款异步通知报错Illegal key size or default parameters 的解决办法

    问题原因: Java几乎各种常用加密算法都能找到对应的实现.因为美国的出口限制,Sun通过权限文件(local_policy.jar.US_export_policy.jar)做了相应限制.因此存在一 ...

随机推荐

  1. phpcms 2008 变量覆盖漏洞

    一. 启动环境 1.双击运行桌面phpstudy.exe软件 2.点击启动按钮,启动服务器环境 二.代码审计 1.双击启动桌面Seay源代码审计系统软件 3.点击新建项目按钮,弹出对画框中选择(C:\ ...

  2. dedecms 5.7 任意前台用户修改漏洞

    一. 启动环境 1.双击运行桌面phpstudy.exe软件 2.点击启动按钮,启动服务器环境 二.代码审计 1.双击启动桌面Seay源代码审计系统软件 2.点击新建项目按钮,弹出对画框中选择(C:\ ...

  3. 解决centos7服务器shadows已启动但是无法连接的问题

    firewall-cmd --permanent --add-port=8989/tcp firewall-cmd --reload 这是由于centos7防火墙并没有开放ss端口的问题 添加json ...

  4. FOC实现概述

    FOC原理框图如下: 其中涉及到两种坐标转换: 1. Clark变换:常规的三相坐标系→静止的二相坐标系α.β 正变换矩阵 $\left[ {\begin{array}{*{20}{c}}{\sqrt ...

  5. CLion入门教程

    1. 说点什么 以下我将介绍地表最强(可能是之一,别打我) C/C++ 开发 IDE--CLion,以及如何使用它来快乐刷题. 工欲善其事,必先利其器.一个好的编程工具对写代码或是做题来说格外重要,尤 ...

  6. MyBatis 与 Hibernate 有哪些不同?

    1.Mybatis 和 hibernate 不同,它不完全是一个 ORM 框架,因为 MyBatis 需要 程序员自己编写 Sql 语句. 2.Mybatis 直接编写原生态 sql,可以严格控制 s ...

  7. Thread 类的 sleep()方法和对象的 wait()方法都可以让线 程暂停执行,它们有什么区别?

    sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程 暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁依然保 持,因此休眠时间结束后会自动恢复(线程回 ...

  8. MariaDB 存储引擎一览(官方文档翻译)

    inline-translate.translate { } inline-translate.translate::before, inline-translate.translate::after ...

  9. osi七层模型&tcp/udp

    1.TCP/UDP协议 1.1 TCP协议 可靠,速度慢,全双工通信 建立连接三次握手,断开连接四次挥手 建立起链接之后,发送每条消息都有回执,为了保证数据的完整性,还有重传机制 数据传输:有收必有发 ...

  10. 智能指针中C++重载'->'符号是怎么实现的

    例如下面的代码: class StrPtr{ public: StrPtr() : _ptr(nullptr){} //拷贝构造函数等省略... std::string* operator->( ...