439

I had asked a question about this earlier, but it didn't get answered right and led nowhere.

So I've clarified few details on the problem and I would really like to hear your ideas on how could I fix this or what should I try.

I have Java 1.6.0.12 installed on my Linux server and the code below runs just perfectly.

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

Today I installed Java 1.6.0.26 on my server user and when I try to run my application, I get the following exception. My guess would be that it has something to do with the Java installation configuration because it works in the first one, but doesn't work in the later version.

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

Line 25 is: c.init(Cipher.DECRYPT_MODE, secretKeySpec);

Notes:
* java.security on server's 1.6.0.12 java directory matches almost completely with the 1.6.0.26 java.security file. There are no additional providers in the first one.
* The previous question is here.

Kirby
  • 15,127
  • 10
  • 89
  • 104
Rihards
  • 10,241
  • 14
  • 58
  • 78
  • 5
    Refer to [How to install Java Cryptography Extension unlimited strength jurisdiction policy files](http://opensourceforgeeks.blogspot.in/2014/09/how-to-install-java-cryptography.html) – Aniket Thakur Sep 21 '14 at 19:11
  • 4
    This may also be thrown as error:`Caused by: java.security.InvalidKeyException: Illegal key size` (without the "or default parameters") in Java 8 – EagleEye208 May 03 '16 at 21:04
  • Just use the OpenJDK and it will work. – Rodrigo Asensio Jan 04 '17 at 20:45
  • @RodrigoAsensio : I'm using the OpenJDK and it doesn't work with it. You have to install the unlimited Strength Jurisdiction Policy Files jar files. And then it will work. – anjanb Jul 25 '17 at 06:50
  • 7
    Update to @AniketThakur answer. Since Java 9 and Java 8u151 there's no need to download and manually install jurisdiction policy files anymore. To enable unlimited cryptography, one can use the new crypto.policy Security property. If the new Security property (crypto.policy) is set in the java.security file, or has been set dynamically by using the Security.setProperty() call before the JCE framework has been initialized, that setting will be honored. By default, the property will be undefined. – Marcin Kłopotek Oct 20 '17 at 11:03

19 Answers19

751

Most likely you don't have the unlimited strength file installed now.

You may need to download this file:

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 (only required for versions before Java 8 u162)

Extract the jar files from the zip and save them in ${java.home}/jre/lib/security/.

Robert
  • 39,162
  • 17
  • 99
  • 152
James Black
  • 41,583
  • 10
  • 86
  • 166
  • Since these files go under the jre directory, if I use them for development, the end user will need them installed as well in order to run my application correct (ie: The unlimited strength is not compiled in)? – wufoo Apr 10 '12 at 15:04
  • @wufoo - Correct, the user has to have them also. – James Black Apr 10 '12 at 17:03
  • 1
    @aroth - Which version of the JDK are you using and which file did you install? – James Black Oct 24 '12 at 11:09
  • @JamesBlack - I'm using Java 6 Update 37, Windows, 64-bit version. I installed both JAR files contained in the download that the answer links to. – aroth Oct 25 '12 at 08:03
  • @aroth - Did you follow the directions as to where to place these files? Try typing 'java -version' from the command console and see if the version in your path is the same as what you working with. – James Black Oct 26 '12 at 00:23
  • 3
    @JamesBlack - Yep, and to make sure all the bases were covered I put the JAR's under `Java/jre/lib/security`, `Java/jdk/lib/security`, and `Java/jdk/jre/lib/security`. Running 'java -version' returns the expected details. – aroth Oct 26 '12 at 04:02
  • 5
    For IBM's SDK (e.g., WebSphere), download the unlimited jurisdiction policy files from https://www14.software.ibm.com/webapp/iwm/web/preLogin.do?source=jcesdk – quietmint Dec 27 '13 at 21:13
  • I was running Rails with JRuby and this page solved my problem: http://deployingjruby.blogspot.com/2013/05/how-to-run-rails-400rc1-on-jruby.html – mlunoe Aug 06 '14 at 22:22
  • I am unable to replace or override local and Us extracted jar files, it is giving permission denied error. – Ravindra Feb 03 '15 at 13:17
  • 1
    @Ravindra - You may need to have administrator privileges – James Black Feb 03 '15 at 18:44
  • Hi @JamesBlack downgrading my Java version did the trick for me – Ravindra Feb 17 '15 at 12:53
  • @arik - The permission is to replace the file, not to run it. If it was installed as administrator or root then a standard user can't overwrite it. – James Black Feb 24 '15 at 01:37
  • Thanks, overwrite the local_policy.jar and US_export_policy.jar in both your JDK's jdk1.6.0_25\jre\lib\security\ and in your JRE's lib\security\ folder. – Mohammed Akdim Sep 16 '15 at 09:14
  • I'm unable to download the files. I'm getting the following error message: `Thank you for accessing the Oracle Software Delivery Cloud. Due to your country location, we are unable to process your request. [...] If you wish to purchase or evaluate our products on a 30-day trial please contact the appropriate Sales Representative for your country.` Is this a transient problem or a not well declared license restriction? – acorello Nov 10 '16 at 16:13
  • On Windows I had to update the JAVA_HOME environment variable to the latest installed JRE before this took effect even though I was running the application with the latest JRE. Run: "echo %JAVA_HOME%" to check if the environment variable is set correctly, it should be the same JRE you added the export policy jars to. – Ben Holland Apr 18 '17 at 19:45
  • didn't work for me , I was running this as a java program in android studio, I also replaced these jars at home/Android/android-studio/jre/jre/libs/security/ . after that error changed to java.lang.RuntimeException: Stub! at android.util.Base64.encodeToString(Base64.java:24) – user3024215 May 23 '17 at 07:01
  • @logic.town : Where are you from ? from the JCE download readme, I see "Due to the import restrictions of some countries, the jurisdiction policy files distributed with the Java SE 7 software have built-in restrictions on available cryptographic strength." – anjanb Jul 25 '17 at 06:55
  • 4
    Since Java 9 and Java 8u151 there's no need to download and manually install jurisdiction policy files anymore. To enable unlimited cryptography, one can use the new crypto.policy Security property. If the new Security property (crypto.policy) is set in the java.security file, or has been set dynamically by using the Security.setProperty() call before the JCE framework has been initialized, that setting will be honored. By default, the property will be undefined. – Marcin Kłopotek Oct 20 '17 at 11:03
  • 4
    So, this upvoted answer is now out of date, and deprecated. How do we upvote or supress this answer so that https://stackoverflow.com/a/46857694/2808798 can be the "accepted" answer? – Jesse Adelman Apr 16 '18 at 21:27
  • 3
    @JesseAdelman - Unfortunately this is almost 7 years old, not much can be done. Whomever asked would need to change it. – James Black Apr 18 '18 at 22:15
  • If i'm not misundertanding [this](https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8170157), version 8u161 should be the very first build bundled with unlimited strength – Andrea Di Lisio Mar 28 '19 at 08:35
  • here is the direct download link for Java 8 ( no account required) http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip – Edward D. Wilson Apr 25 '20 at 21:13
  • For those who want to avoid installing "Unlimited Strength" JCE policy files there is this another thread going on: https://stackoverflow.com/questions/1179672/how-to-avoid-installing-unlimited-strength-jce-policy-files-when-deploying-an – Flávio Henrique Oct 26 '21 at 17:26
57

The JRE/JDK/Java 8 jurisdiction files can be found here:

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

Like James said above:
Install the files in ${java.home}/jre/lib/security/.

Saad Malik
  • 1,598
  • 1
  • 18
  • 20
  • 2
    Tried using 6 and 7, but they didn't work. Had to install 8. Thanks. – Jason Kim Feb 23 '15 at 22:10
  • 9
    New release JDK 8u151 has "New Security property to control crypto policy". Now it's a property change to switch. The bottom line: remove the "#" from the line "#crypto.policy=unlimited" in "lib\security\java.security" to enable using 256-bit keys. http://www.oracle.com/technetwork/java/javase/8u151-relnotes-3850493.html – hemisphire Oct 19 '17 at 15:53
  • 1
    Thanks! Since this is a security property, you can also call Security.setProperty("crypto.policy", "unlimited"). Source: @hemisphire 's link :) – Fluf Oct 23 '17 at 09:58
47

With Java 9, Java 8u161, Java 7u171 and Java 6u181 the limitation is now disabled by default. See issue in Java Bug Database.


Beginning with Java 8u151 you can disable the limitation programmatically.

In older releases, JCE jurisdiction files had to be downloaded and installed separately to allow unlimited cryptography to be used by the JDK. The download and install steps are no longer necessary.

Instead you can now invoke the following line before first use of JCE classes (i.e. preferably right after application start):

Security.setProperty("crypto.policy", "unlimited");
Sebastian S
  • 4,420
  • 4
  • 34
  • 63
43

For JAVA 7 the download link is jce-7-download

Copy the two downloaded jars in Java\jdk1.7.0_10\jre\lib\security
Take a backup of older jars to be on safer side.

For JAVA 8 the download link is jce-8-download
Copy the downloaded jars in Java\jdk1.8.0_45\jre\lib\security
Take a backup of older jars to be on safer side.

C Deepak
  • 1,258
  • 1
  • 17
  • 23
35

This is a code only solution. No need to download or mess with configuration files.

It's a reflection based solution, tested on java 8

Call this method once, early in your program.

//Imports

import javax.crypto.Cipher;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;

//method

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
}

Credits: Delthas

Jako
  • 2,489
  • 3
  • 28
  • 38
  • 6
    Please note that this may violate the Java SE licensing agreement: _D. JAVA TECHNOLOGY RESTRICTIONS. You may not create, modify, or change the behavior of, or authorize your licensees to create, modify, or change the behavior of, classes, interfaces, or subpackages that are in any way identified as "java", "javax", "javafx", "sun", “oracle” or similar convention as specified by Oracle in any naming convention designation.[...]_ [source](http://www.oracle.com/technetwork/java/javase/downloads/java-se-archive-license-1382604.html) – SimMac Jan 07 '18 at 13:47
18

In Java, by default AES supports a 128 Bit key, if you plans to use 192 Bit or 256 Bit key, java complier will throw Illegal key size Exception, which you are getting.

The solution is as victor & James suggested, you will need to download JCE (Java Cryptography Extension) as per your JRE version,(java6, java7 or java8).

The JCE zip contains following JAR:

  1. local_policy.jar
  2. US_export_policy.jar

You need to replace these jar form your <JAVA_HOME>/jre/lib/security. if you are on a unix system the will probably refer to /home/urs/usr/lib/jvm/java-<version>-oracle/

Sometimes just replacing local_policy.jar, US_export_policy.jar in security folder doesn't work on unix, so I suggest to copy security folder to your desktop first, replace the jar's @Desktop/security folder, delete the security folder from /jre/lib/ & move the Desktop security folder to /jre/lib/.

eg :: sudo mv security /usr/lib/jvm/java-7-oracle/jre/lib

tostao
  • 2,803
  • 4
  • 38
  • 61
Ketan
  • 439
  • 4
  • 5
  • I tried this on ubuntu 18 but it does not work.. I am thinking if we need to do a restart of PC or tomcat server for the change to be applied? – Borgy Manotoy Oct 09 '20 at 12:14
  • "Java compiler will throw illegal key size Exception"?? -- No, the compiler will *not* throw that Exception! At compile time, the key sizes of the two partners are not yet even known! this happens much later at runtime, when the SSL handshake takes place... :-) – Lanzelot Jun 16 '23 at 12:42
16

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

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

evanxsummers
  • 191
  • 2
  • 5
16

I experienced the same error while using Windows 7 x64, Eclipse, and JDK 1.6.0_30. In the JDK installation folder there is a jre folder. This threw me off at first as I was adding the aforementioned jars to the JDK's lib/security folder with no luck. Full path:

C:\Program Files\Java\jdk1.6.0_30\jre\lib\security

Download and extract the files contained in the jce folder of this archive into that folder.

anon
  • 4,163
  • 3
  • 29
  • 26
5

the problem is the content of the file default_local.policy in local_policy.jar in the folder jre\lib\security, if you install the 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;
};

if you do not need worldwide valid settings you simply can edit this file and change the content to

// Country-specific policy file for countries with no limits on crypto strength.
grant {
    // There is no restriction to any algorithms.
    permission javax.crypto.CryptoAllPermission;
};

this is what get if you download the JCE from Oracle.

max
  • 781
  • 6
  • 3
5

There's a short discussion of what appears to be this issue here. The page it links to appears to be gone, but one of the responses might be what you need:

Indeed, copying US_export_policy.jar and local_policy.jar from core/lib/jce to $JAVA_HOME/jre/lib/security helped. Thanks.

jww
  • 97,681
  • 90
  • 411
  • 885
RHSeeger
  • 16,034
  • 7
  • 51
  • 41
  • Thanks, but I had `US_export_policy.jar` and `local_policy.jar` in my lib/security folder already once I installed Java.. And I couldn't find core/lib/jce by the way in my Java installation folder. – Rihards Jun 26 '11 at 11:20
4

If you are using Linux distribution with apt and have added webupd8 PPA, you can simply run the command

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

Other updates:

  1. The Unlimited Strength Jurisdiction Policy Files are included with Java 9 and used by default
  2. Starting with Java 8 Update 161, Java 8 defaults to the Unlimited Strength Jurisdiction Policy.
  3. 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

Before Java 8 Update 151 rest of the answers hold valid. Download JCE Unlimited Strength Jurisdiction Policy Files and replace.

For more details, you can refer to my personal blog post below - How to install Java Cryptography Extension (JCE) unlimited strength jurisdiction policy files

Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
4

I also got the issue but after replacing existing one with the downloaded (from JCE) one resolved the issue. New crypto files provided unlimited strength.

Dev G
  • 1,387
  • 4
  • 26
  • 43
3

By default, Java only supports AES 128 bit (16 bytes) key sizes for encryption. If you do not need more than default supported, you can trim the key to the proper size before using Cipher. See javadoc for default supported keys.

This is an example of generating a key that would work with any JVM version without modifying the policy files. Use at your own discretion.

Here is a good article on whether key 128 to 256 key sizes matter on AgileBits Blog

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);
}
keaplogik
  • 2,369
  • 2
  • 25
  • 26
  • The [Cipher](https://docs.oracle.com/javase/7/docs/api/javax/crypto/Cipher.html) classes documentation points to valid key sizes for each crypto type. – keaplogik Jan 12 '16 at 14:43
  • See the Oracle document [Cipher (Encryption) Algorithms](https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#Cipher) AES: Advanced Encryption Standard as specified by NIST in FIPS 197. Also known as the Rijndael algorithm by Joan Daemen and Vincent Rijmen, AES is a 128-bit block cipher supporting keys of 128, 192, and 256 bits. – zaph Jan 12 '16 at 14:44
  • That may be true, but it is only required by each Java version to support 128-bit as specified in class documentation. Test it yourself and you will find you will need the policy jar from [James Black's answer](http://stackoverflow.com/a/6481658/1387421) to do other key sizes – keaplogik Jan 12 '16 at 14:50
  • Any AES implementation that did not support 256-bit keys would be essentially useless because it would not be able to decrypt substantial numbers of AES encryptions using 256-bit keys. – zaph Jan 12 '16 at 14:53
  • You must include the jars in [James Black's answer](http://stackoverflow.com/a/6481658/1387421) to get other key size support! Why do you think it was upvoted so many times? It is because the JVM does not ship with default support and without modifying the policy file! – keaplogik Jan 12 '16 at 14:56
  • 1
    If a 256-bit key is needed the best solution, perhaps the only solution, is to install the Policy file if needed, not truncate the key potentially weakening the security and may not be possible in the case of interoperability. – zaph Jan 12 '16 at 15:37
  • Also SHA1 should not be used in new work, at a minimum SHA256 should be used. But further when deriving an encryption key from text the current best practice is to use a function such as PBKDF2 (Password Based Key Derivation Function 2), not a hash or even HMAC. – zaph Jan 12 '16 at 20:15
2

Starting from Java 9 or 8u151, you can use comment a line in the file:

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

And change:

#crypto.policy=unlimited

to

crypto.policy=unlimited
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
1

Default JDK supports encryption only through 128 bit keys becuase of American restrictions. So to support encryption from 256 bit long key we have to replace local_policy.jar and US_export_policy.jars in $JAVA_HOME/java-8-oracle/jre/lib/security folder otherwise it will give:

java.security.InvalidKeyException: Illegal key size or default

jkr
  • 5
  • 2
Sulabh Jain
  • 342
  • 1
  • 9
1

there are two options to solve this issue

option number 1 : use certificate with less length RSA 2048

option number 2 : you will update two jars in jre\lib\security whatever you use java http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

or you use IBM websphere or any application server that use its java . the main problem that i faced i used certification with maximum length ,when i deployed ears on websphere the same exception is thrown

Java Security: Illegal key size or default parameters?

i updated java intsalled folder in websphere with two jars https://www14.software.ibm.com/webapp/iwm/web/reg/pick.do?source=jcesdk&lang=en_US

you can check reference in link https://www-01.ibm.com/support/docview.wss?uid=swg21663373

Shaaban Ebrahim
  • 9,766
  • 1
  • 18
  • 20
1

Make sure you use the latest version of JDK/JRE.

In my case, I had put JCE into JRE folder, but it didn't help. It happened because I was running my project from the IDE directly (using JDK).

Then I updated my JDK and JRE to the latest version (1.8.0_211) and the problem had gone.

More details: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8170157

0

You need to go there

/jdk1.8.0_152 | /jre | /lib | /security | java.security and uncomment the

#crypto.policy=unlimited

to

crypto.policy=unlimited
Fzum
  • 1,695
  • 1
  • 12
  • 15
0

Download the JCE Files from below Link for Java 6

https://www.oracle.com/java/technologies/jce-6-download.html

Download the JCE Files from below Link for Java 8

https://www.oracle.com/java/technologies/javase-jce8-downloads.html

Copy the files downloaded from the above Link and Go to JDK Installed Directory

/Users/ik/jdk1.8.0_72/jre/lib/security

Paste & Replace the files from the directory. Restart your application & the error must be resolved.

Ishaq Khan
  • 929
  • 9
  • 7