63

我有一个测试在我的开发 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 提供程序时才有效。

4

5 回答 5

134

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

Java 9 及更高版本

Unlimited Strength Jurisdiction Policy Files 包含在 Java 9 中并默认使用(请参阅Java 9 迁移指南中的安全更新)。

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

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

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

如果您的国家或使用需要更严格的策略,那么有限的 Java 加密策略文件仍然可用。

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

请参阅文件crypto.policy中的 Security 属性 <java-home>/conf/security/java.security,或 Java Platform, Standard Edition Security Developer's Guide 中的Cryptographic Strength Configuration

Java 8 及更早版本

Java 8 更新 161 及更高版本

从 Java 8 Update 161 开始,Java 8 默认采用 Unlimited Strength Jurisdiction Policy。如果您收到此错误,则可能表明配置已更改为limited. 有关将其更改回unlimited.

Java 8 更新 151 及更高版本

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

  1. 下载无限强度的 JCE 政策文件。

  2. 解压并解压下载的文件。

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

    README.txt                   This file
    local_policy.jar             Unlimited strength local policy file
    US_export_policy.jar         Unlimited strength US export policy file
    
  3. 安装无限强度策略 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 这样长时间运行的服务器进程尤其重要)。

于 2010-10-05T13:52:36.580 回答
8

我遇到了类似的问题,但就我而言,存在路径错误。

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.

于 2013-05-29T17:12:56.427 回答
1

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

于 2010-10-05T13:58:38.640 回答
1

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

For this and above version, you do not need to download the jar files related to security.Because, local_policy.jar and US_export_policy.jar is already included in these versions under the path- \jre\lib\security\policy (JAVA_HOME refers to your current java installation folder) The only chng you need to make is in java.security file which is present in /jre/lib/security - uncomment the line - crypto.policy=unlimited

于 2018-04-05T08:48:17.070 回答
0

确保您知道 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

于 2017-10-05T21:58:18.457 回答