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 文件完全匹配。第一个中没有其他提供程序。
* 上一个问题在这里。

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

您可能需要下载此文件:

Java 加密扩展 (JCE( 无限强度管辖权策略文件 6

Java 加密扩展 (JCE( 无限强度管辖权策略文件 7 下载

Java

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

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

JRE/JDK/Java 8 管辖文件可以在这里找到:

Java 加密扩展 (JCE( 无限强度管辖权策略文件 8 下载

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

对于 Java 9、Java

8u161、Java 7u171 和 Java 6u181,默认情况下禁用此限制。请参阅 Java 错误数据库中的问题。


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

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

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

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

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

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

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

这是一个纯代码解决方案。无需下载或弄乱配置文件。

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

学分:德尔塔斯

在 Java 中,默认情况下 AES 支持 128 位密钥,如果您打算使用 192 位或 256 位密钥,java 编译器将抛出非法密钥大小异常,您正在得到。

解决方案是正如victor&James所建议的那样,您需要根据JRE版本(java6,java7或java8(下载JCE(Java Cryptography Extension(。

JCE zip 包含以下 JAR:

  1. local_policy.jar
  2. US_export_policy.jar

您需要从您的<JAVA_HOME>/jre/lib/security中更换这些罐子。 如果您使用的是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 安全/usr/lib/jvm/java-7-oracle/jre/lib

"Java 加密扩展 (JCE( 无限强度管辖权策略文件 6">

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

我在使用 Windows 7 x64、Eclipse 和 JDK 1.6.0_30 时遇到了同样的错误。在 JDK 安装文件夹中有一个jre文件夹。起初这让我很失望,因为我将上述罐子添加到 JDK 的库/安全文件夹中,但没有运气。完整路径:

C:Program FilesJavajdk1.6.0_30jrelibsecurity

下载此存档的jce文件夹中包含的文件并将其解压缩到该文件夹中。

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

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

问题是文件的内容

default_local.policylocal_policy.jar 中的文件夹 JRE\lib\security,如果你安装了 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时得到的。

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

如果您使用的是带有 apt 的 Linux 发行版并添加了 webupd8 PPA,您只需运行以下命令即可

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

其他更新:

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

    crypto.policy=unlimited

    确保使用以管理员身份运行的编辑器编辑文件。策略更改仅在重新启动 JVM 后生效

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

有关更多详细信息,您可以参考下面的我的个人博客文章 -如何安装 Java 加密扩展 (JCE( 无限强度管辖权策略

文件

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

这是生成密钥的示例,

该密钥适用于任何 JVM 版本,而无需修改策略文件。自行决定使用。

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

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 9 或 8u151 开始,您可以在文件中使用注释一行:

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

并更改:

#crypto.policy=unlimited

crypto.policy=unlimited
有两种

选择可以解决此问题

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

选项2:您将在jrelibsecurity中更新两个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?

我用两个jar更新了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 中查看参考

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

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

然后我将JDK和JRE更新到最新版本(1.8.0_211(,问题就消失了。

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

由于美国的限制,默认 JDK 仅支持通过 128 位密钥进行加密。因此,要支持从 256 位长密钥加密,我们必须替换文件夹中local_policy.jarUS_export_policy.jars $JAVA_HOME/java-8-oracle/jre/lib/security否则它会得到:

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

你需要去那里

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

#crypto.policy=unlimited

crypto.policy=unlimited

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

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

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

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

复制从上述链接下载的文件,然后转到JDK安装目录

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

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

最新更新