How can I check, in Java code, if the current JVM have unlimited strength cryptography available?
-
1a nice way to do it: http://stackoverflow.com/questions/11538746 – Chris Dec 13 '13 at 14:43
-
Note that since java 8u152 ultimate will be the default on clean installation. see https://www.oracle.com/technetwork/java/javase/8u152-relnotes-3850503.html – Haim Raman Nov 05 '18 at 05:55
9 Answers
In the same spirit as the answer of Dan Cruz, but with a single line of code and without going trough exceptions:
boolean limit = Cipher.getMaxAllowedKeyLength("RC5")<256;
So a complete program might be:
import javax.crypto.Cipher;
public class TestUCE {
public static void main(String args[]) throws Exception {
boolean unlimited =
Cipher.getMaxAllowedKeyLength("RC5") >= 256;
System.out.println("Unlimited cryptography enabled: " + unlimited);
}
}

- 51,991
- 13
- 150
- 199

- 615
- 4
- 4
-
tested and this worked, returning 'false' and 'true' respectively. Thank you. – eis Feb 12 '15 at 13:44
-
3
-
2This answer uses the `"RC5"` transform, a rather obscure stream cipher that is *not in the list of required algorithms*, it checks against 256 (which may be available in future restricted JREs and it also doesn't handle the exception well. Please take a look at [my answer](http://stackoverflow.com/a/33849265/589259) that resolves this. – Maarten Bodewes Nov 21 '15 at 22:27
If you are on Linux and you have installed the JDK (but Beanshell is not available), you can check with the runscript
command provided with the JDK.
jrunscript -e 'exit (javax.crypto.Cipher.getMaxAllowedKeyLength("RC5") >= 256 ? 0 : 1);'; echo $?
This returns a 0
status code if the Unlimited Cryptography is available, or 1
if not available. Zero is the correct 'success' return value for shell functions, and non-zero indicates a failure.

- 18,480
- 13
- 68
- 76

- 451
- 4
- 2
-
Just an FYI that jrunscript is included in the Oracle JDK, so you might have to go looking for it. On a RedHat/CentOS/Fedora system you can do `rpm -ql jdk | grep jrunscript` to find it. – slm Jan 20 '16 at 03:40
-
1I'm trying to run this in windows. Is there a special escape character I need to use? – user1207381 Feb 15 '17 at 21:03
-
This works like a champ on macOS. This should also work fine under PowerShell. – Ryan J. McDonough Apr 11 '17 at 01:45
-
2Windows version: `jrunscript -e "exit (println(javax.crypto.Cipher.getMaxAllowedKeyLength(\"RC5\") >= 256));"` – chance Jan 31 '20 at 12:34
I think you could probably use Cipher.getMaxAllowedKeyLength(), while also comparing the cypher you're using to known lists of "good", secure cyphers, such as AES.
Here's a reference article that lists maximum key size jurisdiction limitations that were current as of Java 1.4 (these likely haven't changed, unless the law has also changed - see below).
If you are operating in a nation that has cryptographic export/import restrictions, you'd have to consult the law in your nation, but it's probably safe to assume in these situations that you don't have unlimited strength cryptography available (by default) in your JVM. Putting it another way, assuming you're using the official JVM from Oracle, and you happen to live in a nation against which the U.S. has leveled export restrictions for cryptography (and since Oracle is a United States company, it would be subject to these restrictions), then you could also assume in this case that you don't have unlimited strength available.
Of course, that doesn't stop you from building your own, and thereby granting yourself unlimited strength, but depending on your local laws, that might be illegal.
This article outlines the restrictions on export to other nations, from the Unites States.
-
1I find it pretty hard to check from Java whether or not I'm running in a machine under USA export laws... – Chi-Lan Oct 31 '11 at 17:04
-
Yeah, I suppose there's no API for that. I think Dan Cruz's answer is probably the closest you can get. – jefflunt Oct 31 '11 at 18:05
-
The way how to check if restrictions apply is documented in the method Cipher.getMaxAllowedKeyLength
:
If JCE unlimited strength jurisdiction policy files are installed,
Integer.MAX_VALUE
will be returned.
This means that if any value other than (or indeed lower than) Integer.MAX_VALUE
is returned that restrictions do apply.
Even more information is in the JavaDoc of the method below:
/**
* Determines if cryptography restrictions apply.
* Restrictions apply if the value of {@link Cipher#getMaxAllowedKeyLength(String)} returns a value smaller than {@link Integer#MAX_VALUE} if there are any restrictions according to the JavaDoc of the method.
* This method is used with the transform <code>"AES/CBC/PKCS5Padding"</code> as this is an often used algorithm that is <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#impl">an implementation requirement for Java SE</a>.
*
* @return <code>true</code> if restrictions apply, <code>false</code> otherwise
*/
public static boolean restrictedCryptography() {
try {
return Cipher.getMaxAllowedKeyLength("AES/CBC/PKCS5Padding") < Integer.MAX_VALUE;
} catch (final NoSuchAlgorithmException e) {
throw new IllegalStateException("The transform \"AES/CBC/PKCS5Padding\" is not available (the availability of this algorithm is mandatory for Java SE implementations)", e);
}
}
Note that since Java 9 the unlimited crypto policies are installed by default (with those affected by import / export regulations having to install the limited crypto policies instead). So this code would mainly be required for backwards compatibility and/or other runtimes.

- 90,524
- 13
- 150
- 263
-
Added this additional answer because the [accepted answer](http://stackoverflow.com/a/7954769/589259) is not very definitive and the answer [that currently has the most upvotes](http://stackoverflow.com/a/8607735/589259) uses RC5, a rather obscure stream cipher that is not in the list of required algorithms, it checks against 256 (which may be available in future *restricted* JREs and it also doesn't handle the exception well. – Maarten Bodewes Nov 21 '15 at 22:20
-
1Note that you can use `getMaxAllowedKeyLength("foo")` and still get the right answer. I've found that as long as the argument isn't `null` or `""`, you'll get the answer you're looking for. – Christopher Schultz Mar 03 '16 at 15:57
-
1Right. But I'd rather make sure my code is not vulnerable against implementation changes... – Maarten Bodewes Mar 03 '16 at 16:47
This is a complete copy paste version to allow for testing
import javax.crypto.Cipher;
import java.security.NoSuchAlgorithmException;
class Test {
public static void main(String[] args) {
int allowedKeyLength = 0;
try {
allowedKeyLength = Cipher.getMaxAllowedKeyLength("AES");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
System.out.println("The allowed key length for AES is: " + allowedKeyLength);
}
}
To run
javac Test.java
java Test
If JCE is not working output: 128
JCE is working something like: 2147483647

- 4,073
- 3
- 27
- 47
-
The function `getMaxAllowedKeyLength` may not return a valid AES key size and as such this answer is incorrect. Personally I hate `printStackTrace` as the code keeps running. If you throw a `RuntimeException` instead then you would not have to assign the wrong value 0 to `allowedKeyLength`. – Maarten Bodewes Dec 06 '18 at 15:52
If you are using Linux, you can check it easily with this command
java -version ; \
echo 'System.err.println(javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding").getMaxAllowedKeyLength("AES"));' \
| java -cp /usr/share/java/bsh-*.jar bsh.Interpreter >/dev/null
If the output is something like that, unlimited strength cryptography is not available
java version "1.7.0_76"
Java(TM) SE Runtime Environment (build 1.7.0_76-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.76-b04, mixed mode)
128

- 73
- 1
- 7
You can check it in one step from the command line by using groovy :
groovysh -e 'javax.crypto.Cipher.getMaxAllowedKeyLength("AES")'
If the result is 2147483647
, you have unlimited cryptography.
On older version of groovy, you have to remove the -e
:
groovysh 'javax.crypto.Cipher.getMaxAllowedKeyLength("AES")'

- 56,620
- 24
- 188
- 240
NOTE: Please use jefflunt's answer or KonstantinSpirov's answer. This answer is not a valid answer since it will always return true
. I am leaving this answer here only because it is referenced elsewhere in answers and comments and is useful as a reference only.
You could use the following to initialize a static final boolean
somewhere that you can then use for testing unlimited crypto support (since AES 256-bit is only supported if the unrestricted policy is installed).
boolean isUnlimitedSupported = false;
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES", "SunJCE");
kgen.init(256);
isUnlimitedSupported = true;
} catch (NoSuchAlgorithmException e) {
isUnlimitedSupported = false;
} catch (NoSuchProviderException e) {
isUnlimitedSupported = false;
}
System.out.println("isUnlimitedSupported=" + isUnlimitedSupported);
// set static final variable = isUnlimitedSupported;

- 15,194
- 6
- 41
- 65
-
2
-
@eis, I agree. This will always return true. Updated to note better answers. – Go Dan Feb 12 '15 at 16:06
-
3This doesn't work because `Cipher` tests for the allowed key sizes, while `KeyGenerator` does not. The restrictions are not specific to a provider. Furthermore, instantiating a `KeyGenerator` is not a very efficient or logical method to check for the restrictions. **Please remove incorrect answers.** – Maarten Bodewes Nov 21 '15 at 22:23
I recently had to do add a JCE check and my solution evolved to the following snippet. This was a groovy script, but it should be easy to convert to standard java method with a try catch. This has been tested with Java 7 & Java 8.
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.SecretKey;
// Make a blank 256 Bit AES Key
final SecretKey secretKey = new SecretKeySpec(new byte[32], "AES");
final Cipher encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// This line will throw a invalid key length exception if you don't have
// JCE Unlimited strength installed
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey);
// If it makes it here, you have JCE installed

- 177
- 1
- 12
-
1There are a few issues with your scheme. First of all, it relies on an exception during the running of the code to perform the test. This makes it harder to debug. It could be that there are future restrictions on e.g. RSA that do not influence the key size of AES, in which case the test would fail. Third, it requires the creation of spurious objects that are not really required at all to perform the test. That said, the test would of course work for Java 7 & 8 and the transformation that you chose is at least mandatory for Java SE implementations. – Maarten Bodewes Nov 22 '15 at 12:14