本文目錄
一、錯誤信息
您正在使用Java加密擴展開發漂亮的應用程序,並且使用長度超過128位的密鑰時,您會遇到以下錯誤:
Caused by: java.security.InvalidKeyException: Illegal key size or default parameters
您所做的一切都是正確的:JDK在默認情況下有一個專門的密鑰大小限制,因此您不能使用密鑰超過128位的加密。
Java官方文檔:Oracle’s documentation。
二、錯誤原因
其實,Java幾乎各種常用加密算法都能找到對應的實現。但是因爲美國的出口限制,Sun通過權限文件(local_policy.jar、US_export_policy.jar)做了相應限制。因此存在一些問題:
- 密鑰長度上不能滿足需求(如:java.security.InvalidKeyException: Illegal key size or default parameters);
- 部分算法未能支持,如MD4、SHA-224等算法;
- API使用起來還不是很方便;一些常用的進制轉換輔助工具未能提供,如Base64編碼轉換、十六進制編碼轉換等工具。
Oracle在其官方網站上提供了無政策限制權限文件(Unlimited Strength Jurisdiction Policy Files),我們只需要將其部署在JRE環境中,就可以解決限制問題。
由於一些國家政府的進口控制限制,Sun Microsystems提供的JDK 5.0附帶的管轄政策文件指定可以使用“強”但有限的加密。
有些國家對加密算法使用的允許密鑰強度有限制:
這些文件的“無限強度”版本表明對密碼強度沒有限制,適用於居住在合格國家(即大多數國家)的人。但只有“強大”的版本才能被輸入那些政府強制限制的國家。JCE框架將強制執行已安裝的管轄權策略文件中指定的限制。
三、解決方案
那麼,如何刪除密鑰的大小限制呢?
方法1:通過反射進行修改
/**
* 1、通過反射去除JCE加密限制,此方法只限於Java1.8,直接複製(可能報錯,引用java.lang.reflect下的包即可)
* 2、在main方法中加密操作之前調用一下這個方法就OK了
*/
private static void removeJceLimit() {
try {
Field field = Class.forName("javax.crypto.JceSecurity").getDeclaredField("isRestricted");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, false);
log.info("============= remove the key size restriction Success =============");
} catch (ClassNotFoundException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
ex.printStackTrace(System.err);
}
}
注意:使用方法1,解決這個問題的時候,自測加密是可以的,但是,在解密的時候 還會報錯,所以最穩妥的辦法還是方法2。
方法2:下載官方Jar包修改
您可以使用無限制強度的策略jar替換現有的JCE jar,從而消除最大密鑰限制(JAVA官網提供兩個版本的Jar包,以下是官網下載地址):
1、對於Java 5 的JCE jar包下載地址如下:Java 5.0 無政策限制文件
2、對於Java 6 的JCE jar包下載地址如下:Java 6 無政策限制文件
3、對於Java 7 的JCE jar包下載地址如下:Java 7 無政策限制文件
4、對於Java 8 的JCE jar包下載地址如下:Java 8 無政策限制文件
5、對於Java 其他版本 的JCE jar包下載地址如下:其他版本 無政策限制文件
將上面zip文件中提取的local_policy.jar和US_export_policy.jar複製到$JAVA_HOME/jre/lib/security。
然後只需重新啓動java應用程序,異常就會消失。
具體步驟:
1、下載的壓縮包中僅有一個目錄,也就是jce目錄。該目錄中包含了4個文件:README.txt、COPYRIGHT.html、local_policy.jar和US_export_policy.jar。其中包含的兩個jar文件正是此次配置中用到的文件。
2、我們可以查看上述README.txt文件,你需要在JDK的JRE環境中,或者是JRE環境中配置上述兩個jar文件。
3、切換到%JDK_Home%\jre\lib\security目錄下,對應覆蓋local_policy.jar和US_export_policy.jar兩個文件。同時,你可能有必要在%JRE_Home%\lib\security目錄下,也需要對應覆蓋這兩個文件。
4、配置權限文件的最終目的是爲了使應用在運行環境中獲得相應的權限,可以加強應用的安全性。通常,我們在應用服務器上安裝的是JRE,而不是JDK。所以很有必要在應用服務器的%JRE_Home%\lib\security目錄下,對應覆蓋這兩個權限文件。
【參考資料】
Andrea Fortuna:https://www.andreafortuna.org/2016/06/08/java-tips-how-to-fix-the-invalidkeyexception-illegal-key-size-or-default-parameters-runtime/