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

时间:2011-06-26 01:40:16

标签: 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

第25行是: c.init(Cipher.DECRYPT_MODE, secretKeySpec);

备注:
*服务器的 1.6.0.12 java目录中的java.security几乎完全匹配 1.6.0.26 java.security文件。第一个提供者没有其他提供者 *上一个问题是here

19 个答案:

答案 0 :(得分:689)

您很可能现在没有安装无限强度文件。

您可能需要下载此文件:

Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6

Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7 Download

Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 Download(仅适用于Java 8 u162之前的版本)

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

答案 1 :(得分:50)

可在此处找到JRE / JDK / Java 8管辖区文件:

Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 Download

像詹姆斯上面说的那样:
${java.home}/jre/lib/security/

中安装文件

答案 2 :(得分:39)

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

将两个下载的jar复制到Java \ jdk1.7.0_10 \ jre \ lib \ security
中 备份较旧的罐子更安全。

对于JAVA 8,下载链接为jce-8-download
将下载的jar复制到Java \ jdk1.8.0_45 \ jre \ lib \ security
中 备份较旧的罐子更安全。

答案 3 :(得分:31)

对于Java 9,Java 8u161Java 7u171Java 6u181,默认情况下现在禁用此限制。请参阅issue in Java Bug Database

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

  

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

相反,您现在可以在首次使用JCE类之前调用​​以下行(即最好在应用程序启动后立即调用):

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

答案 4 :(得分:29)

这是仅代码解决方案。无需下载或搞乱配置文件。

它是基于反射的解决方案,在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

答案 5 :(得分:16)

“Java密码术扩展(JCE)无限强度管辖政策文件6”

http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

答案 6 :(得分:16)

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

解决方案是胜利者和James建议,你需要根据你的JRE版本(java6,java7或java8)下载JCE(Java Cryptography Extension)。

JCE zip包含以下JAR:

  1. local_policy.jar
  2. 的US_export_policy.jar
  3. 您需要从<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 /&amp;将Desktop安全性文件夹移动到/ jre / lib /.

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

答案 7 :(得分:15)

使用Windows 7 x64,Eclipse和JDK 1.6.0_30时遇到了同样的错误。在JDK安装文件夹中有一个jre文件夹。当我将上述罐子添加到JDK的lib / security文件夹时没有运气,这让我一开始就放弃了。完整路径:

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

this archive jce文件夹中包含的文件下载并解压缩到该文件夹​​中。

答案 8 :(得分:5)

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

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

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

Uri uri=Uri.parse("file://"+ "form.pdf");

如果您从Oracle下载JCE,那就是这样。

答案 9 :(得分:5)

对这个问题here进行了简短的讨论。 links to似乎已消失的页面,但其中一个响应可能就是您所需要的:

  

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

答案 10 :(得分:4)

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

答案 11 :(得分:2)

默认情况下,Java仅支持AES 128位(16字节)密钥大小进行加密。如果您不需要超过支持的默认值,则可以在使用Cipher之前将密钥修剪为适当的大小。有关默认支持的密钥,请参阅javadoc

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

以下是一篇关于密钥128到256密钥大小是否在AgileBits Blog

上重要的文章
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);
}

答案 12 :(得分:2)

如果您将Linux发行版与apt一起使用并添加了webupd8 PPA,则只需运行命令

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

其他更新:

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

    crypto.policy=unlimited

    确保使用管理员身份运行的编辑器来编辑文件。 仅在重新启动JVM

  4. 之后,策略更改才会生效

Java 8 Update 151 之前,其余答案仍然有效。下载JCE无限强度管辖权政策文件并替换。

有关更多详细信息,您可以参考以下我的个人博客文章- How to install Java Cryptography Extension (JCE) unlimited strength jurisdiction policy files

答案 13 :(得分:1)

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

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

并改变:

#crypto.policy=unlimited

crypto.policy=unlimited

答案 14 :(得分:1)

有两种方法可以解决此问题

选项1:使用长度较短的RSA 2048的证书

选项2:,您将更新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?

我用两个罐子更新了Websphere中的Java集成文件夹  https://www14.software.ibm.com/webapp/iwm/web/reg/pick.do?source=jcesdk&lang=en_US

您可以在链接https://www-01.ibm.com/support/docview.wss?uid=swg21663373

中检查引用

答案 15 :(得分:1)

默认JDK仅通过128位密钥支持加密,因为美国限制。 因此,要支持256位长密钥加密,我们必须替换local_policy.jar文件夹中的US_export_policy.jars$JAVA_HOME/java-8-oracle/jre/lib/security,否则它将提供:

  

java.security.InvalidKeyException:非法密钥大小或默认

从链接中可以理解罐子和详细概念:

easybook4u.com

答案 16 :(得分:0)

您需要去那里

/jdk1.8.0_152    | / jre         | / lib               | /安全                     | java.security 并取消注释

#crypto.policy=unlimited

crypto.policy=unlimited

答案 17 :(得分:0)

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

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

然后我将我的JDK和JRE更新到最新版本(1.8.0_211),问题不再存在。

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

答案 18 :(得分:0)

从下面的链接下载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

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