You don't need a policy file anymore.
It's important, so I'll say it again. You don't need a policy file anymore.
Java uses the standard library Cipher class to handle AES ciphers without the use of third-party libraries. However, AES encryption seems to be subject to US export restrictions, and the standard can only handle keys up to 128 bits. In countries like Japan that are not subject to this export control, it is well known that you need to download a separate unlimited strength policy file from Oracle and overwrite it on your system.
It's nice to be able to use AES 256 ciphers by replacing the policy file, but ... to be honest, it's very annoying. It's a hassle to explain this to someone who doesn't know what happened, and it's also a hassle to replace it every time you update the JDK. If it's just a hassle, there's still the risk of forgetting or making mistakes.
In Java 9, this policy file is pre-shipped with the JDK and can now be controlled by simply changing the security property crypto.policy
.
limited
→ Limited strength (up to AES 128 can be used as before)The security property crypto.policy
can be set in two ways, but since Java 9, it defaults to ** ʻunlimited`, so you really need to do nothing. there is not.
Security.setProperty ()
Since it can be set programmatically, it is free from policy file replacement and prior configuration file rewriting. However, please note that once the JCE framework is initialized, it cannot be switched in the middle, as described below.
Security.setProperty("crypto.policy", "unlimited");
int length = Cipher.getMaxAllowedKeyLength("AES"); // => 2147483647
Security.setProperty("crypto.policy", "limited");
int length = Cipher.getMaxAllowedKeyLength("AES"); // => 128
java.security
fileYou can also pre-edit $ JAVA_HOME / conf / security / java.security
. Please note that the directory hierarchy is slightly different from Java 8
$ cd /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/conf/security/ #macOS example
$ tree
.
├── java.policy
├── java.security #Set in this file
├── javaws.policy
└── policy
├── README.txt
├── limited
│ ├── default_US_export.policy
│ ├── default_local.policy
│ └── exempt_local.policy
└── unlimited
├── default_US_export.policy
└── default_local.policy
$ grep "crypto.policy=" java.security
crypto.policy=unlimited
■ 2018-01-17 Addendum (thx. @Yehara) From 8u161, the default has changed to ʻunlimited` in Java 8. Even in a Java 8 environment, you can use AES 256 ciphers by simply updating to the latest JDK: congratulations:
Up to this point, it ends with "I want to go to Java 9 soon: weary:", but in fact, this mechanism also applies to Java 8 8u151. It is included from /javase/8u151-relnotes-3850493.html#JDK-8157561). This means that Java 8 users can now use AES 256 ciphers simply by setting the security property crypto.policy
.
However, there are some differences from the Java 9 specifications, so be aware of the following points.
limited
), so you need to explicitly change it to ʻunlimited`.You can enable unlimited strength encryption in one of the following ways:
Security.setProperty ()
java.security
fileNote that unlike Java 9, it is $ JAVA_HOME / jre / lib / security / java.security
$ cd /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/security/
$ tree
.
├── blacklist
├── blacklisted.certs
├── cacerts
├── java.policy
├── java.security #Set in this file
├── policy
│ ├── limited
│ │ ├── US_export_policy.jar
│ │ └── local_policy.jar
│ └── unlimited
│ ├── US_export_policy.jar
│ └── local_policy.jar
└── trusted.libraries
$ grep "crypto.policy=" java.security
# (equivalent to crypto.policy=limited)
#crypto.policy=unlimited
For reference, up to 8u144 was the following directory hierarchy
$ cd /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/security/
$ tree
.
├── US_export_policy.jar #Replace this file
├── blacklist
├── blacklisted.certs
├── cacerts
├── java.policy
├── java.security
├── local_policy.jar #Replace this file
└── trusted.libraries
,
local_policy.jar`$ JAVA_HOME / jre / lib / security /
as before. However, in this case, the condition is that crypto.policy
is unspecified (default value).This is the method of 1. that is set programmatically using Security.setProperty ()
, but be careful because it does not work as expected in some applications. The point is that it must be set ** before initializing the JCE framework **.
For example, the following code looks fine, but the length2
is also 128. This is because the JCE framework is initialized when the Cipher class is referenced for the first time, and at this point it is decided which policy will be used.
int length = Cipher.getMaxAllowedKeyLength("AES"); // => 128
Security.setProperty("crypto.policy", "unlimited");
int length2 = Cipher.getMaxAllowedKeyLength("AES"); // => 128 (!)
It's fine if you're writing a simple command line tool, but it can be a problem for web applications that run on Tomcat, for example. This is because if you have HTTPS communication enabled, the JCE framework will be initialized before your application code is executed.
Even in the same Web application, if you are using an embedded container in Spring Boot etc., since the class with the main method that is the entry point is on the application side, the security property in your own class is faster than the initialization of the container. Can be replaced.
In this article, I introduced that the policy file replacement that was required when working with AES 256 ciphers in Java is no longer needed in Java 9 and Java 8.
Since it is no longer necessary to replace the policy file in advance, it is human nature to choose the method of using Security.setProperty ()
1. However, in Java 8, the type of application being developed Please note that some may not work. You should move quickly to Java 9, which defaults to ʻunlimited`.