java.security.InvalidKeyException:android 中的非法密钥大小或默认参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24907530/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java.security.InvalidKeyException: Illegal key size or default parameters in android
提问by Captain Nakou
I got the following error and I got a little stuck: Exception in thread "main"
我收到以下错误并且有点卡住了:线程“main”中的异常
java.security.InvalidKeyException: Illegal key size or default parameters
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1011)
at javax.crypto.Cipher.implInit(Cipher.java:786)
at javax.crypto.Cipher.chooseProvider(Cipher.java:849)
at javax.crypto.Cipher.init(Cipher.java:1213)
at javax.crypto.Cipher.init(Cipher.java:1153)
at net.nakou.indie.wtext.engineClass.Session.cryptString(Session.java:52)
I'm stuck because all the answers I've found talk about the Java Cryptography Extension (JCE)which be normally included into the android SDK. So I think my problem is not this one.
我被卡住了,因为我找到的所有答案都在谈论通常包含在 android SDK 中的 Java加密扩展 (JCE)。所以我认为我的问题不是这个。
I must have forgotten something, but I can't find what. Maybe my code is wrong (it's my first approach of cryptography in Java, I'm not an expert, and the following code is mostly some copy-pastes of tutorials).
我一定忘记了什么,但我找不到什么。也许我的代码是错误的(这是我在 Java 中的第一个密码学方法,我不是专家,以下代码主要是一些教程的复制粘贴)。
I use this code to crypt and decrypt a String :
我使用此代码来加密和解密 String :
public String cryptString(String s) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException, BadPaddingException, IllegalBlockSizeException {
byte[] KeyData = this.cryptKey.getBytes();
SecretKeySpec KS = new SecretKeySpec(KeyData, "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, KS);
String ret = new String(cipher.doFinal(s.getBytes("UTF-8")));
return ret;
}
public String decryptString(byte[] s) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
byte[] KeyData = this.cryptKey.getBytes();
SecretKeySpec KS = new SecretKeySpec(KeyData, "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.DECRYPT_MODE, KS);
String ret = new String(cipher.doFinal(s));
return ret;
}
And the following key :
以及以下键:
private String cryptKey = "qkjll5@2md3gs5Q@FDFqf";
Thank you guys.
谢谢你们。
采纳答案by VenomVendor
private String cryptKey = "qkjll5@2md3gs5Q@FDFqf";
private String cryptKey = "qkjll5@2md3gs5Q@FDFqf";
By default Java supports only 128-bit encryption
默认情况下,Java 仅支持 128 位加密
128bits == 16Bytes == 16 Chars.
128 位 == 16 字节 == 16 个字符。
So cryptKey
cannot exceed 16 characters.
所以cryptKey
不能超过 16 个字符。
If you want to exceed more than 16 character you have to install Java Cryptography Extension (JCE) Unlimited Strength.
如果要超过 16 个字符,则必须安装 Java Cryptography Extension (JCE) Unlimited Strength。
回答by Sulabh Jain
Default JDK supports encryption only through 128 bit keys becuase of American restrictions. So to support encryption from 256 bit long key we have to replace local_policy.jar and US_export_policy.jars in $JAVA_HOME/java-8-oracle/jre/lib/security folder otherwise it will give java.security.InvalidKeyException: Illegal key size or default
由于美国的限制,默认 JDK 仅支持通过 128 位密钥进行加密。因此,为了支持 256 位长密钥的加密,我们必须替换 $JAVA_HOME/java-8-oracle/jre/lib/security 文件夹中的 local_policy.jar 和 US_export_policy.jars 否则它会给出 java.security.InvalidKeyException: Illegal key size 或默认
回答by Kiran Sutar
This is a code only solution. No need to download or mess with configuration files.
这是一个只有代码的解决方案。无需下载或弄乱配置文件。
It's a reflection based solution, tested on java 8
这是一个基于反射的解决方案,在 java 8 上测试过
Call this method once, early in your program or while application is being started.
在程序早期或应用程序启动时调用此方法一次。
//Imports
//导入
import javax.crypto.Cipher;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;
//method
//方法
public static void fixKeyLength() {
String errorString = "Failed manually overriding key-length permissions.";
int newMaxKeyLength;
try {
if ((newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES")) < 256) {
Class c = Class.forName("javax.crypto.CryptoAllPermissionCollection");
Constructor con = c.getDeclaredConstructor();
con.setAccessible(true);
Object allPermissionCollection = con.newInstance();
Field f = c.getDeclaredField("all_allowed");
f.setAccessible(true);
f.setBoolean(allPermissionCollection, true);
c = Class.forName("javax.crypto.CryptoPermissions");
con = c.getDeclaredConstructor();
con.setAccessible(true);
Object allPermissions = con.newInstance();
f = c.getDeclaredField("perms");
f.setAccessible(true);
((Map) f.get(allPermissions)).put("*", allPermissionCollection);
c = Class.forName("javax.crypto.JceSecurityManager");
f = c.getDeclaredField("defaultPolicy");
f.setAccessible(true);
Field mf = Field.class.getDeclaredField("modifiers");
mf.setAccessible(true);
mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);
f.set(null, allPermissions);
newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES");
}
} catch (Exception e) {
throw new RuntimeException(errorString, e);
}
if (newMaxKeyLength < 256)
throw new RuntimeException(errorString); // hack failed
}
回答by Aniket Thakur
There have been updates since Java 8/9
自 Java 8/9 以来有更新
- The Unlimited Strength Jurisdiction Policy Files are included with Java 9and used by default
- Starting with Java 8 Update 161, Java 8 defaults to the Unlimited Strength Jurisdiction Policy.
Starting with Java 8 Update 151, the Unlimited Strength Jurisdiction Policy is included with Java 8 but not used by default. To enable it, you need to edit the java.security file in
<java_home>/jre/lib/security
(for JDK) or<java_home>/lib/security
(for JRE). Uncomment (or include) the linecrypto.policy=unlimited
Make sure you edit the file using an editor run as administrator. The policy change only takes effect after restarting the JVM
- Unlimited Strength Jurisdiction Policy Files 包含在Java 9 中并默认使用
- 从Java 8 Update 161 开始,Java 8 默认为 Unlimited Strength Jurisdiction Policy。
从 Java 8 Update 151 开始,无限强度管辖权策略包含在 Java 8 中,但默认情况下不使用。要启用它,您需要在
<java_home>/jre/lib/security
(对于 JDK)或<java_home>/lib/security
(对于 JRE)中编辑 java.security 文件。取消注释(或包括)该行crypto.policy=unlimited
确保使用以管理员身份运行的编辑器编辑文件。策略更改仅在重新启动 JVM 后生效
Before Java 8 Update 151you have to download JCE Unlimited Strength Jurisdiction Policy files and replace.
在Java 8 Update 151之前,您必须下载 JCE Unlimited Strength Jurisdiction Policy 文件并替换。
For more details see How to install Java Cryptography Extension (JCE) unlimited strength jurisdiction policy files
有关更多详细信息,请参阅如何安装 Java Cryptography Extension (JCE) 无限强度权限策略文件
PS: Above link goes to my personal blog that has additional details.
PS:以上链接指向我的个人博客,其中包含更多详细信息。
回答by Sidharth Taneja
You can remove the maximum key restriction by replacing the existing JCE jarswith unlimited strength policy jars.
您可以通过使用无限强度策略 jar替换现有的 JCE jar来移除最大密钥限制。
For JAVA 8 the download JCE Jar from link - https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
对于 JAVA 8,从链接下载 JCE Jar - https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
(/usr/libexec/java_home -v to find Java_HOMEin Mac)
(/usr/libexec/java_home -v在 Mac 中查找 Java_HOME)
Copy local_policy.jarand US_export_policy.jarextracted from above zip file to the $JAVA_HOME/jre/lib/security
将从上面的zip文件中提取的local_policy.jar和US_export_policy.jar复制到$JAVA_HOME/jre/lib/security