Java安全:非法密钥大小或默认参数?

我之前问过一个关于这个问题的问题,但它没有得到正确的回答,也没有任何结果。

我已经澄清了这个问题的一些细节,我真的很想听听你的想法,我该如何解决这个问题,或者我应该尝试什么。

我在我的Linux服务器上安装了Java 1.6.0.12,下面的代码运行得很完美。

String key = "av45k1pfb024xa3bl359vsb4esortvks74sksr5oy4s5serondry84jsrryuhsr5ys49y5seri5shrdliheuirdygliurguiy5ru";
try {
Cipher c = Cipher.getInstance("ARCFOUR");


SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "ARCFOUR");
c.init(Cipher.DECRYPT_MODE, secretKeySpec);


return new String(c.doFinal(Hex.decodeHex(data.toCharArray())), "UTF-8");


} catch (InvalidKeyException e) {
throw new CryptoException(e);
}

今天我在我的服务器用户上安装了Java 1.6.0.26,当我试图运行我的应用程序时,我得到了以下异常。我的猜测是,这与Java安装配置有关,因为它在第一个版本中可以工作,但在后面的版本中不能工作。

Caused by: java.security.InvalidKeyException: Illegal key size or default parameters
at javax.crypto.Cipher.a(DashoA13*..) ~[na:1.6]
at javax.crypto.Cipher.a(DashoA13*..) ~[na:1.6]
at javax.crypto.Cipher.a(DashoA13*..) ~[na:1.6]
at javax.crypto.Cipher.init(DashoA13*..) ~[na:1.6]
at javax.crypto.Cipher.init(DashoA13*..) ~[na:1.6]
at my.package.Something.decode(RC4Decoder.java:25) ~[my.package.jar:na]
... 5 common frames omitted
< p > 第25行是: c.init(Cipher.DECRYPT_MODE, secretKeySpec); < / p > < p > 注: < br > * java。服务器的1.6.0.12 java目录上的security几乎完全匹配1.6.0.26 java. xml目录。安全文件。在第一个中没有其他的提供者 *前面的问题是在这里.

477525 次浏览

有一个简短的讨论似乎是这个问题在这里。页面链接似乎消失了,但其中一个响应可能是你需要的:

实际上,将US_export_policy.jar和local_policy.jar从core/lib/jce复制到$JAVA_HOME/jre/lib/security有帮助。谢谢。

很可能你现在还没有安装无限力量文件。

你可能需要下载此文件:

Java密码扩展(JCE)无限强度管辖策略文件 < / > < / p >

Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7下载 .

Java加密扩展(JCE)无限强度管辖策略文件8下载(仅适用于Java 8 u162之前的版本)

从zip中提取jar文件并将它们保存在${java.home}/jre/lib/security/中。

我也得到了这个问题,但在替换现有的下载(从JCE)一个解决了这个问题。新的加密文件提供了无限的力量。

我在使用Windows 7 x64、Eclipse和JDK 1.6.0_30时遇到了同样的错误。在JDK安装文件夹中有一个jre文件夹。当我把前面提到的jar文件添加到JDK的lib/security文件夹时,一开始这让我很困惑。完整路径:

C:\Program Files\Java\jdk1.6.0_30\jre\lib\security

下载并解压包含在这个档案jce文件夹中的文件到该文件夹中。

对于JAVA 7,下载链接是jce-7-download

将下载的两个jar文件拷贝到Java\jdk1.7.0_10\jre\lib\security
为了安全起见,备份一些旧的罐子。< / p > 对于JAVA 8,下载链接是jce-8-download
将下载的jar文件拷贝到Java\jdk1.8.0_45\jre\lib\security
中 为了安全起见,备份一些旧的罐子。< / p >

JRE/JDK/ java8司法管辖区文件可以在这里找到:

Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8下载 .

就像James上面说的:
安装${java.home}/jre/lib/security/中的文件

问题是jre \ lib \安全文件夹中的local_policy.jar中的default_local.policy文件的内容,如果你安装了JRE:

// Some countries have import limits on crypto strength. This policy file
// is worldwide importable.


grant {
permission javax.crypto.CryptoPermission "DES", 64;
permission javax.crypto.CryptoPermission "DESede", *;
permission javax.crypto.CryptoPermission "RC2", 128,
"javax.crypto.spec.RC2ParameterSpec", 128;
permission javax.crypto.CryptoPermission "RC4", 128;
permission javax.crypto.CryptoPermission "RC5", 128,
"javax.crypto.spec.RC5ParameterSpec", *, 12, *;
permission javax.crypto.CryptoPermission "RSA", *;
permission javax.crypto.CryptoPermission *, 128;
};

如果您不需要全球有效设置,您可以简单地编辑此文件并将内容更改为

// Country-specific policy file for countries with no limits on crypto strength.
grant {
// There is no restriction to any algorithms.
permission javax.crypto.CryptoAllPermission;
};

这是你从Oracle下载JCE得到的结果。

在Java中,默认情况下AES支持128位密钥,如果你计划使用192位或256位密钥,Java编译器将抛出非法密钥大小异常,这是你得到的。

解决方案是victor &James建议,您需要根据您的JRE版本(java6, java7或java8)下载JCE (Java密码扩展)。

JCE压缩包包含以下JAR:

  1. local_policy.jar
  2. US_export_policy.jar
你需要从你的<JAVA_HOME>/jre/lib/security中替换这些jar。 如果您在unix系统上,则可能会引用/home/urs/usr/lib/jvm/java-<version>-oracle/

有时只是替换安全文件夹中的local_policy.jar, US_export_policy.jar在unix上不起作用,所以我建议先将安全文件夹复制到您的桌面,替换jar的@Desktop/security文件夹,删除/jre/lib/ &移动桌面安全文件夹到/jre/lib/。

sudo mv security /usr/lib/jvm/java-7-oracle/jre/lib

默认情况下,Java只支持AES 128位(16字节)密钥大小的加密。如果你不需要超过默认值的支持,你可以在使用Cipher之前将键修剪成合适的大小。默认支持的键请参见javadoc

这是一个生成密钥的示例,该密钥可以在不修改策略文件的情况下使用任何JVM版本。请自行斟酌使用。

这是一篇关于AgileBits博客上128到256键大小是否重要的好文章

SecretKeySpec getKey() {
final pass = "47e7717f0f37ee72cb226278279aebef".getBytes("UTF-8");
final sha = MessageDigest.getInstance("SHA-256");


def key = sha.digest(pass);
// use only first 128 bit (16 bytes). By default Java only supports AES 128 bit key sizes for encryption.
// Updated jvm policies are required for 256 bit.
key = Arrays.copyOf(key, 16);
return new SecretKeySpec(key, AES);
}

这是一个代码解决方案。不需要下载或混乱的配置文件。

这是一个基于反射的解决方案,在Java 8上测试

在程序的早期调用此方法一次。

/ /进口

import javax.crypto.Cipher;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;

/ /方法

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
}

学分:Delthas

由于美国限制,默认JDK只支持128位密钥加密。 因此,为了支持256位长密钥的加密,我们必须替换local_policy.jarUS_export_policy.jars文件夹中的$JAVA_HOME/java-8-oracle/jre/lib/security,否则它将给出:

invalidkeyexception:非法密钥大小或默认值

在Java 9中,Java 8 u161Java 7 u171Java 6 u181现在默认禁用限制。看到Java错误数据库中的问题


Java 8 u151开始,可以通过编程方式禁用限制。

在旧版本中,JCE权限文件必须单独下载和安装,以允许JDK使用无限的加密。不再需要下载和安装步骤。

相反,你现在可以在第一次使用JCE类之前调用下面的行(即最好是在应用程序启动之后):

Security.setProperty("crypto.policy", "unlimited");

从Java 9或8u151开始,你可以在文件中使用注释行:

<JAVA_HOME>/jre/lib/security/java.security

和变化:

#crypto.policy=unlimited

crypto.policy=unlimited

有两个选项可以解决这个问题

选项1:使用长度小于RSA 2048的证书

你将在jre\lib\security中更新两个jar 无论你使用java http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

或者您使用IBM websphere或任何使用其java的应用服务器。 我遇到的主要问题是我使用了最大长度的认证,当我在websphere上部署耳朵时,抛出了相同的异常

Java Security: Illegal key size or default parameters?

我更新Java安装文件夹在websphere与两个jar https://www14.software.ibm.com/webapp/iwm/web/reg/pick.do?source=jcesdk&lang=en_US < / p >

你可以在链接https://www-01.ibm.com/support/docview.wss?uid=swg21663373中检查引用

如果您正在使用带有apt的Linux发行版并添加了webupd8 PPA,则可以简单地运行该命令

apt-get install oracle-java8-unlimited-jce-policy

其他更新:

  1. 无限强度管辖策略文件包含在Java 9中,默认使用
  2. java8 Update 161开始,Java 8默认为无限强度管辖策略。
  3. java8更新151开始,无限强度管辖策略包含在Java 8中,但默认情况下不使用。要启用它,您需要编辑java。<java_home>/jre/lib/security(适用于JDK)或<java_home>/lib/security(适用于JRE)中的安全文件。取消注释(或包括)该行

    crypto.policy=unlimited

    确保您使用以管理员身份运行的编辑器编辑该文件。 策略修改需要重启JVM

  4. 后生效

java8更新151之前,其余答案是有效的。下载JCE无限强度管辖政策文件并替换。

要了解更多细节,你可以参考我下面的个人博客文章- 如何安装Java密码扩展(JCE)无限强度权限策略文件 < / p >

你需要去那里

< p > / jdk1.8.0_152 | / jre | / lib | /安全 | java.security 并取消

.注释
#crypto.policy=unlimited

crypto.policy=unlimited

确保你使用JDK/JRE的最新版本

在我的例子中,我已经将JCE放入JRE文件夹中,但这并没有帮助。发生这种情况是因为我直接从IDE(使用JDK)运行我的项目。

然后我将JDK和JRE更新到最新版本(1.8.0_211),问题已经解决了。

更多详细信息:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8170157

从下面的Java 6链接下载JCE文件

https://www.oracle.com/java/technologies/jce-6-download.html

从下面的Java 8链接下载JCE文件

https://www.oracle.com/java/technologies/javase-jce8-downloads.html

复制上述链接中下载的文件,进入JDK安装目录

/Users/ik/jdk1.8.0_72/jre/lib/security

粘贴,替换目录中的文件。重新启动应用程序必须解决这个错误。