65

I have a test which runs great on my development MacBook Pro, but fails to run in continuous integration TeamCity server.

The error is following:

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

Both development box and TeamCity uses Java 1.6 and I use BouncyCastle library for the need of special AES encryption.

The code is following:

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"));
}

UPDATE

Looks like according to the selected answer I have to modify something on my TeamCity installation and it will possibly affect some user installations - so its not a good choice I have to switch to another crypto library to do that without limitations. So probably bouncy castle will help.

UPDATE 2

I actually switched to use BouncyCastle to avoid this limitation. Note this only works if you use own BC classes directly, not the BC provider.

3
  • Alternatively, you can use weaker keys :-) (128 bit is still considered to be secure, and you don't need to install that policy file) Commented Oct 5, 2010 at 15:53
  • Btw, Bouncy Castle has same restriction: bouncycastle.org/wiki/display/JA1/Frequently+Asked+Questions (first q/a) Commented Oct 5, 2010 at 16:09
  • 1
    Bouncy Castle provides two APIs -- the FAQ you link to is about Bouncy Castle Provider, which is a JCE implementation and has the JCE restrictions, and a Bouncy Castle-specific API which is not limited.
    – Jules
    Commented Mar 2, 2012 at 16:11

6 Answers 6

139

This error means that your Java virtual machine uses a policy that only allows restricted cryptography key sizes due to US export laws.

Java 9 and higher

The Unlimited Strength Jurisdiction Policy Files are included with Java 9 and used by default (see Security Updates in the Java 9 Migration Guide).

If you get this error with Java 9, it might mean the policy configuration has been changed to a more restrictive policy (limited), see the instructions from the migration guide:

JCE Jurisdiction Policy File Default is Unlimited

If your application previously required the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files, then you no longer need to download or install them. They are included in the JDK and are activated by default.

If your country or usage requires a more restrictive policy, the limited Java cryptographic policy files are still available.

If you have requirements that are not met by either of the policy files provided by default, then you can customize these policy files to meet your needs.

See the crypto.policy Security property in the <java-home>/conf/security/java.security file, or Cryptographic Strength Configuration in the Java Platform, Standard Edition Security Developer's Guide.

Java 8 and earlier

Java 8 Update 161 and higher

Starting with Java 8 Update 161, Java 8 defaults to the Unlimited Strength Jurisdiction Policy. If you receive this error, it could indicate the configuration has been changed to limited. See instructions in the next section on Java 8 Update 151, or the previous section on Java 9, for changing this back to unlimited.

Java 8 Update 151 and higher

Starting with Java 8 Update 151, the Unlimited Strength Jurisdiction Policy is included with Java 8 but not used by default. To enable it, you need to edit the java.security file in <java_home>/jre/lib/security (for JDK) or <java_home>/lib/security (for JRE). Uncomment (or include) the line

crypto.policy=unlimited

Make sure you edit the file using an editor run as administrator.

The policy change only takes effect after restarting the JVM (this is especially important for long-running server processes like Tomcat).

For backwards compatibility, installing the policy files as documented in the next section will still work as well.

Before Java 8 Update 151

For Java 8 Update 144 and earlier, you need to install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files (available at Oracle).

To install these files (from the README.txt in the download):

  1. Download the unlimited strength JCE policy files.

  2. Uncompress and extract the downloaded file.

    This will create a subdirectory called jce. This directory contains the following files:

    README.txt                   This file
    local_policy.jar             Unlimited strength local policy file
    US_export_policy.jar         Unlimited strength US export policy file
    
  3. Install the unlimited strength policy JAR files.

    In case you later decide to revert to the original "strong" but limited policy versions, first make a copy of the original JCE policy files (US_export_policy.jar and local_policy.jar). Then replace the strong policy files with the unlimited strength versions extracted in the previous step.

    The standard place for JCE jurisdiction policy JAR files is:

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

Note for the JDK it is in jre/lib/security.

The new policy file only takes effect after restarting the JVM (this is especially important for long-running server processes like Tomcat).

6
  • I didn't install JCE USJ specially on my development box but it works there.
    – Vladimir
    Commented Oct 5, 2010 at 14:06
  • Do you think that it can be installed by default there and not installed on server?
    – Vladimir
    Commented Oct 5, 2010 at 14:12
  • @Vladimir: I am not able to find whether Apple bundles unlimited strength policy files or not, but it's not bundled in JVMs provided by Oracle (or Sun previously). If your TeamCity runs on Linux/Windows, you need to install unlimited strength policy files on your build server on your own. Commented Oct 5, 2010 at 14:39
  • 4
    Note that after installing the new policy files, you may need to restart anything that runs through the JVM. I had to do restart Tomcat before my web application picked up on the changes, for example.
    – user
    Commented Mar 21, 2016 at 10:53
  • 1
    Late but: this issue applied and applies to the JCE interface in Java packages from Sun-now-Oracle. Most Linux distros I've seen build their own package(s) from OpenJDK source, and these 'openjdk' packages usually do not have the maximum-128bit policy. Commented Sep 24, 2016 at 4:56
8

I had a similar problem, but in my case, there was a path error.

JAVA_HOME was jdk1.6.0_18, so I put the two jars into jdk1.6.0_18/lib/security, but within jdk1.6.0_18 is the jre directory. Both files should have been put in jdk1.6.0_18/jre/lib/security.

2

The accepted answer assumes that you have administrator permissions to modify files and folders as an administrator.

If that's not the case, for Java 8 Update 151 and higher you can do the following:

  • Create a local file with one line crypto.policy=unlimited.
  • Add -Djava.security.properties=<yourfile> to your java command where <yourfile> is the local file you created

This method should work unless security.overridePropertiesFile is explicitly disabled (enabled by default).

Reference: <java_home>/jre/lib/security/java.security

#
# This is the "master security properties file".
#
# An alternate java.security properties file may be specified
# from the command line via the system property
#
#    -Djava.security.properties=<URL>
#
# This properties file appends to the master security properties file.
# If both properties files specify values for the same key, the value
# from the command-line properties file is selected, as it is the last
# one loaded.
#
# Also, if you specify
#
#    -Djava.security.properties==<URL> (2 equals),
#
# then that properties file completely overrides the master security
# properties file.
#
# To disable the ability to specify an additional properties file from
# the command line, set the key security.overridePropertiesFile
# to false in the master security properties file. It is set to true
# by default.
...
1

In addition to installing policy files, also make sure that CUSTOMLONGSECRETKEY...getBytes() does indeed produce 32 bytes array. I would use CUSTOMLONGSECRETKEY.getBytes(some encoding) and get first 32 bytes from that. Better yet, use whole secret key to derive keys for AES with the size that you need.

2
  • 1
    CUSTOMLONGSECRETKEY is constant = "3C7C6086-CF22-4972-9616-F294DAF77092" for both runs. I wonder how it can affect in TeamCity.
    – Vladimir
    Commented Oct 5, 2010 at 14:19
  • 1
    @Vladimir: I was trying to point that you should use getBytes with explicit encoding, but that doesn't seem to be the problem with your key. I'd try to install that policy files. If you don't do that, you're limited to 128-bit keys for AES. Commented Oct 5, 2010 at 14:33
1

I was facing the same issue for 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

1
  • This worked for me for version 1.8.0_181. Commented Feb 3, 2022 at 17:39
0

Make sure you know the path to JAVA_HOME that your IDE uses. In order to copy to the correct path.

In my case I use IntelliJ: /Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/security

Instead of when i show the $JAVA_HOME in the console. /Users/myuser/.sdkman/candidates/java/current/jre/lib/security

Not the answer you're looking for? Browse other questions tagged or ask your own question.