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