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.
This question is related to
java
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.
"Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6"
http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
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
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.
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.
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:
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
You need to go there
/jdk1.8.0_152 | /jre | /lib | /security | java.security and uncomment the
#crypto.policy=unlimited
to
crypto.policy=unlimited
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
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);
}
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:
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
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
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
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");
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/
.
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
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.
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.
Source: Stackoverflow.com