InvalidKeyException 非法密钥大小

Posted

技术标签:

【中文标题】InvalidKeyException 非法密钥大小【英文标题】:InvalidKeyException Illegal key size 【发布时间】:2011-04-21 05:44:48 【问题描述】:

我有一个测试在我的开发 MacBook Pro 上运行良好,但无法在持续集成 TeamCity 服务器中运行。

错误如下:

java.security.InvalidKeyException: Illegal key size
    at javax.crypto.Cipher.a(DashoA13*..)
    at javax.crypto.Cipher.init(DashoA13*..)
    at javax.crypto.Cipher.init(DashoA13*..)

开发盒和 TeamCity 都使用 Java 1.6,我使用 BouncyCastle 库来满足特殊 AES 加密的需要。

代码如下:

private byte[] aesEncryptedInfo(String info) throws UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidParameterSpecException, InvalidAlgorithmParameterException, NoSuchProviderException 
    Security.addProvider(new BouncyCastleProvider());
    SecretKey secret = new SecretKeySpec(CUSTOMLONGSECRETKEY.substring(0, 32).getBytes(), "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
    cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(VECTOR_SECRET_KEY.getBytes()));
    return cipher.doFinal(info.getBytes("UTF-8"));

更新

看起来根据选择的答案,我必须在我的 TeamCity 安装上修改一些内容,它可能会影响某些用户的安装 - 所以这不是一个好的选择,我必须切换到另一个加密库来不受限制地做到这一点。因此,充气城堡可能会有所帮助。

更新 2

我实际上改用 BouncyCastle 来避免这个限制。请注意,这仅在您直接使用自己的 BC 类而不是 BC 提供程序时才有效。

【问题讨论】:

或者,您可以使用较弱的密钥 :-)(128 位仍然被认为是安全的,您不需要安装该策略文件) 顺便说一句,充气城堡也有同样的限制:bouncycastle.org/wiki/display/JA1/Frequently+Asked+Questions (first q/a) Bouncy Castle 提供了两个 API——您链接到的常见问题解答是关于 Bouncy Castle Provider,它是一个 JCE 实现并具有 JCE 限制,以及一个不受限制的 Bouncy Castle 特定 API。 【参考方案1】:

此错误表示您的 Java 虚拟机使用的策略仅允许受美国出口法律限制的加密密钥大小。

Java 9 及更高版本

Unlimited Strength Jurisdiction Policy Files 包含在 Java 9 中并默认使用(请参阅 Security Updates in the Java 9 Migration Guide)。

如果您在使用 Java 9 时遇到此错误,则可能意味着策略配置已更改为更具限制性的策略 (limited),请参阅迁移指南中的说明:

JCE 管辖政策文件默认为无限

如果您的应用程序以前需要 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files,然后你 不再需要下载或安装它们。它们包含在 JDK,默认激活。

如果您所在的国家或地区需要更严格的政策,则 有限的 Java 加密策略文件仍然可用。

如果您有任何一项政策都不满足的要求 默认提供的文件,那么您可以自定义这些策略文件 以满足您的需求。

请参阅crypto.policy 安全属性 <java-home>/conf/security/java.security 文件,或 Cryptographic Strength Configuration 在 Java 平台中, 标准版安全开发者指南。

Java 8 及更早版本

Java 8 更新 161 及更高版本

从 Java 8 Update 161 开始,Java 8 默认采用 Unlimited Strength Jurisdiction Policy。如果您收到此错误,则可能表明配置已更改为 limited。请参阅 Java 8 Update 151 的下一部分或 Java 9 的上一部分中的说明,将其更改回 unlimited

Java 8 更新 151 及更高版本

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

crypto.policy=unlimited

确保使用以管理员身份运行的编辑器编辑文件。

策略更改仅在重新启动 JVM 后生效(这对于 Tomcat 等长时间运行的服务器进程尤其重要)。

为了向后兼容,安装下一节所述的策略文件仍然有效。

在 Java 8 更新 151 之前

对于 Java 8 Update 144 及更早版本,您需要安装 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files(可在Oracle 获得)。

要安装这些文件(来自下载中的README.txt):

    下载无限强度 JCE 策略文件。

    解压并解压下载的文件。

    这将创建一个名为 jce 的子目录。 该目录包含以下文件:

    README.txt                   This file
    local_policy.jar             Unlimited strength local policy file
    US_export_policy.jar         Unlimited strength US export policy file
    

    安装无限强度策略 JAR 文件。

    如果您后来决定恢复到原来的“强”,但 有限的政策版本,首先制作原始 JCE 的副本 策略文件(US_export_policy.jar 和 local_policy.jar)。然后 用无限的力量代替强大的政策文件 在上一步中提取的版本。

    JCE 管辖政策 JAR 文件的标准位置是:

    <java-home>/lib/security           [Unix]
    <java-home>\lib\security           [Windows]
    

注意 JDK 位于 jre/lib/security 中。

新的策略文件只有在重启 JVM 后才会生效(这对于像 Tomcat 这样长时间运行的服务器进程尤其重要)。

【讨论】:

我没有专门在我的开发盒上安装 JCE USJ,但它可以在那里工作。 你认为那里可以默认安装而不安装在服务器上? @Vladimir:我无法找到 Apple 是否捆绑了无限强度策略文件,但它没有捆绑在 Oracle(或 Sun 之前)提供的 JVM 中。如果您的 TeamCity 在 Linux/Windows 上运行,您需要自行在构建服务器上安装无限强度策略文件。 请注意,安装新的策略文件后,您可能需要重新启动通过 JVM 运行的任何东西。 我必须在我的 Web 应用程序启动之前重新启动 Tomcat例如,变化。 迟到但:此问题适用于来自 Sun-now-Oracle 的 Java 包中的 JCE 接口。我见过的大多数 Linux 发行版都从 OpenJDK 源构建自己的包,而这些“openjdk”包通常没有最大 128 位策略。【参考方案2】:

除了安装策略文件之外,还要确保CUSTOMLONGSECRETKEY...getBytes() 确实生成了 32 字节数组。我会使用 CUSTOMLONGSECRETKEY.getBytes(some encoding) 并从中获取前 32 个字节。更好的是,使用整个密钥为 AES 派生所需大小的密钥。

【讨论】:

CUSTOMLONGSECRETKEY 是常量 = "3C7C6086-CF22-4972-9616-F294DAF77092" 对于两次运行。我想知道它对 TeamCity 有何影响。 @Vladimir:我试图指出您应该使用带有显式编码的 getBytes,但这似乎不是您的密钥的问题。我会尝试安装该策略文件。如果您不这样做,则您只能使用 128 位 AES 密钥。【参考方案3】:

我遇到了类似的问题,但在我的情况下,出现了路径错误。

JAVA_HOME 是 jdk1.6.0_18,所以我把这两个 jar 放到了jdk1.6.0_18/lib/security,但是在 jdk1.6.0_18 里面是 jre 目录。两个文件都应该放在jdk1.6.0_18/jre/lib/security

【讨论】:

【参考方案4】:

确保您知道 IDE 使用的 JAVA_HOME 路径。 为了复制到正确的路径。

就我而言,我使用 IntelliJ: /Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/security

而不是当我在控制台中显示 $JAVA_HOME 时。 /Users/myuser/.sdkman/candidates/java/current/jre/lib/security

【讨论】:

【参考方案5】:

我在 jdk 1.8.0_151 中遇到了同样的问题-

对于这个及以上版本,您不需要下载安全相关的jar文件。因为local_policy.jar和US_export_policy.jar已经包含在这些版本的路径下- \jre\lib\security\policy(JAVA_HOME 指您当前的 java 安装文件夹) 您需要进行的唯一更改是在 /jre/lib/security 中存在的 java.security 文件中 - 取消注释该行 - crypto.policy=unlimited

【讨论】:

以上是关于InvalidKeyException 非法密钥大小的主要内容,如果未能解决你的问题,请参考以下文章

Spring saml:密钥太长,无法展开:invalidkeyexception

java.security.InvalidKeyException:无效的密钥格式... PublicKey 错误

为啥我的 AES 加密会引发 InvalidKeyException?

Java# 256位密钥加密错误,java.security.InvalidKeyException:Illegal key size错误

java.security.InvalidKeyException Illegal key size

AES加密java.security.InvalidKeyException: Illegal key size or default parameters