在微信開發時,訊息介面時,涉及到訊息加密,拋出了 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); } }View Code
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/335077.html
標籤:其他
下一篇:java定時任務調度框架
