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

Posted

技术标签:

【中文标题】Java 安全性:非法密钥大小或默认参数?【英文标题】:Java Security: Illegal key size or default parameters? 【发布时间】:2011-09-22 19:45:06 【问题描述】:

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

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

我在我的 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。

【问题讨论】:

参考How to install Java Cryptography Extension unlimited strength jurisdiction policy files 这也可能在 Java 8 中抛出错误:Caused by: java.security.InvalidKeyException: Illegal key size(没有“或默认参数”) 只要使用 OpenJDK 就可以了。 @RodrigoAsensio :我正在使用 OpenJDK,但它无法使用它。您必须安装无限的强度管辖政策文件 jar 文件。然后它就会起作用。 更新到@AniketThakur 答案。从 Java 9 和 Java 8u151 开始,不再需要下载和手动安装管辖策略文件。要启用无限加密,可以使用新的 crypto.policy 安全属性。如果在 java.security 文件中设置了新的 Security 属性 (crypto.policy),或者在初始化 JCE 框架之前使用 Security.setProperty() 调用动态设置了该设置,则将采用该设置。默认情况下,该属性是未定义的。 【参考方案1】:

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

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

【讨论】:

【参考方案2】:

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

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

【讨论】:

【参考方案3】:

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

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

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

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

【讨论】:

【参考方案4】:

你需要去那里

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

#crypto.policy=unlimited

crypto.policy=unlimited

【讨论】:

【参考方案5】:

如果你使用 apt 的 Linux 发行版并添加了 webupd8 PPA,你可以简单地运行命令

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

其他更新:

    Java 9 包含无限强度管辖策略文件并默认使用 从 Java 8 Update 161 开始,Java 8 默认采用 Unlimited Strength Jurisdiction Policy。

    Java 8 更新 151 开始,Java 8 中包含了 Unlimited Strength Jurisdiction Policy,但默认情况下不使用。要启用它,您需要编辑 <java_home>/jre/lib/security(对于 JDK)或 <java_home>/lib/security(对于 JRE)中的 java.security 文件。取消注释(或包含)该行

    crypto.policy=unlimited

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

Java 8 Update 151 之前,其余答案均有效。下载 JCE Unlimited Strength Jurisdiction Policy Files 并替换。

更多详情,可以参考下面我的个人博文—— How to install Java Cryptography Extension (JCE) unlimited strength jurisdiction policy files

【讨论】:

【参考方案6】:

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

您可能需要下载此文件:

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/ 中。

【讨论】:

@JamesBlack - 是的,为了确保所有基础都被覆盖,我将 JAR 放在 Java/jre/lib/securityJava/jdk/lib/securityJava/jdk/jre/lib/security 下。运行“java -version”会返回预期的详细信息。 对于 IBM 的 SDK(例如 WebSphere),请从 www14.software.ibm.com/webapp/iwm/web/preLogin.do?source=jcesdk 下载无限制管辖策略文件 从 Java 9 和 Java 8u151 开始,不再需要下载和手动安装管辖策略文件。要启用无限加密,可以使用新的 crypto.policy 安全属性。如果在 java.security 文件中设置了新的安全属性 (crypto.policy),或者在初始化 JCE 框架之前使用 Security.setProperty() 调用动态设置了该设置,则该设置将被接受。默认情况下,该属性是未定义的。 所以,这个被赞成的答案现在已经过时了,并且被弃用了。我们如何投票或禁止这个答案,以便***.com/a/46857694/2808798 可以成为“接受”的答案? @JesseAdelman - 不幸的是,这已经快 7 岁了,没什么可做的。谁问谁就需要改变它。【参考方案7】:

有两种方法可以解决这个问题

选项编号 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?

我用两个 jar 更新了 websphere 中的 java intsalled 文件夹 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查看参考

【讨论】:

【参考方案8】:

对于 Java 9、Java 8u161、Java 7u171 和 Java 6u181,现在默认禁用限制。见issue in Java Bug Database。


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

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

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

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

【讨论】:

android 中呢?这些限制方法可以在哪个 API 级别解决?【参考方案9】:

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

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

然后改变:

#crypto.policy=unlimited

crypto.policy=unlimited

【讨论】:

【参考方案10】:

在 Java 中,默认情况下 AES 支持 128 位密钥,如果您计划使用 192 位或 256 位密钥,java 编译器将抛出 Illegal key size 异常,您将得到。

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

JCE zip 包含以下 JAR:

    local_policy.jar US_export_policy.jar

您需要从&lt;JAVA_HOME&gt;/jre/lib/security 中替换这些 jar。 如果您使用的是 unix 系统,则可能会参考 /home/urs/usr/lib/jvm/java-&lt;version&gt;-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

【讨论】:

我在 ubuntu 18 上试过这个,但它不起作用。我在想我们是否需要重新启动 PC 或 tomcat 服务器才能应用更改?【参考方案11】:

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

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

【讨论】:

请注意,这可能违反 Java SE 许可协议:D. JAVA 技术限制。您不得创建、修改或更改其行为,或授权您的被许可人创建、修改或更改以任何方式标识为“java”、“javax”、“ javafx"、"sun"、"oracle" 或 Oracle 在任何命名约定指定中指定的类似约定。[...] source【参考方案12】:

对于 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 备份旧罐子以更安全。

【讨论】:

【参考方案13】:

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

这是一个生成密钥的示例,该密钥适用于任何 JVM 版本,而无需修改策略文件。自行决定使用。

在AgileBits Blog 上有一篇关于 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);

【讨论】:

Cipher 类文档指出了每种加密类型的有效密钥大小。 参见 Oracle 文档 Cipher (Encryption) Algorithms AES:由 NIST 在 FIPS 197 中指定的高级加密标准。也被 Joan Daemen 和 Vincent Rijmen 称为 Rijndael 算法,AES 是一种 128 位分组密码,支持128、192 和 256 位的密钥。 这可能是真的,但只有每个 Java 版本要求它支持类文档中指定的 128 位。自己测试一下,你会发现你需要 James Black's answer 的策略 jar 来做其他密钥大小 任何不支持 256 位密钥的 AES 实现基本上都是无用的,因为它无法使用 256 位密钥解密大量的 AES 加密。 如果需要 256 位密钥,最好的解决方案(也许是唯一的解决方案)是在需要时安装策略文件,而不是截断可能会削弱安全性的密钥,并且在这种情况下可能无法实现的互操作性。【参考方案14】:

问题是 jre\lib\security 文件夹中 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,就会得到这样的结果。

【讨论】:

【参考方案15】:

JRE/JDK/Java 8 权限文件可以在这里找到:

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

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

【讨论】:

尝试使用 6 和 7,但它们不起作用。必须安装 8。谢谢。 新版本 JDK 8u151 具有“控制加密策略的新安全属性”。现在是要切换的属性更改。底线:从 "lib\security\java.security" 中的 "#crypto.policy=unlimited" 行中删除 "#" 以启用使用 256 位密钥。 oracle.com/technetwork/java/javase/8u151-relnotes-3850493.html 谢谢!由于这是一个安全属性,您还可以调用 Security.setProperty("crypto.policy", "unlimited")。来源:@hemisphire 的链接 :)【参考方案16】:

我在使用 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

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

【讨论】:

【参考方案17】:

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

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

【讨论】:

谢谢,但是一旦我安装了 Java,我的 lib/security 文件夹中就已经有 US_export_policy.jarlocal_policy.jar 了。顺便说一下,我在 Java 中找不到 core/lib/jce安装文件夹。【参考方案18】:

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

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

【讨论】:

【参考方案19】:

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

【讨论】:

以上是关于Java 安全性:非法密钥大小或默认参数?的主要内容,如果未能解决你的问题,请参考以下文章

Java基础005 --- 安全管理器可变参数等

InvalidKeyException 非法密钥大小

Java JVM 参数设置大全

Java JVM 参数设置大全

Pybind11 默认参数 numpy 数组或无

如何修改weblogic默认线程池大小