In September 2000, the National Institute of Standards and Technology (NIST) approved the Federal Information Processing Standards (FIPS) 197(pdf 279.5 kb), culminating a multi-year effort to replace the out-of-date Data Encryption Standard (DES). As with DES, the new Advanced Encryption Standard (AES) should continue making inroads into private industry. This article looks at using AES in your Java programs.
AES is a federal standard for private-key or symmetric cryptography. It supports combinations of key and block sizes of 128, 192, and 256. The algorithm chosen for this standard -- called Rijndael -- was invented by two Belgian cryptographers. As part of the evaluation process, the candidate algorithms (including Rijndael) were implemented in the Java language.
The AES standard has been incorporated into several Java technology offerings. Beginning with the Java 2 SDK, Standard Edition (J2SE) v 1.4.0, the Java Cryptography Extension (JCE) was integrated with the SDK and the JRE. Since then, it has no longer been necessary to install the JCE optional package, since support for strong cryptography is now available as part of J2SE. JCE has a provider architecture that enables different providers to be plugged in under a common framework.
Several providers have supported AES in their own clean-room implementations of JCE, or under the existing framework. In Java 2 Platform, Standard Edition v 1.4.2, which is currently under beta, the Sun Provider, referred to as SunJCE, supports AES. Also, the Java Secure Socket Extension (JSSE) supports AES via JCE.
Finally, the Java Card specification version 2.2_01 supports AES with a 128-bit key size.
In this article, we will look primarily at AES support in J2SE, starting with JCE.
Note: The programs listed in this article work only with Java 2 Platform, Standard Edition (J2SE) 1.4.2 installed.
You use AES like any other cipher. To see how, take a look at this JCE sample program. I've modified it to use AES, instead of Blowfish (another symmetric cipher). (I have changed occurrences of Blowfish to AES.)
As you can see, the changes I made to accommodate AES are very minimal -- the JCE framework is very general and extensible.
This sample program demonstrates how to use strong cryptography, which is available by default in most installations. This does mean that support for larger key sizes is normally unavailable. To use AES with 192- and 256-bit key sizes, you need unlimited strength cryptography.
Due to import-control restrictions imposed by some countries, the jurisdiction policy files shipped with the Java 2 SDK, v 1.4 only permit strong cryptography to be used. An unlimited strength version of these files (that is, with no restrictions on cryptographic strength) is available for download, however.
After installing the unlimited strength version, to use key sizes of 192 and 256 bits, simply provide the required length of the key. The following line of code illustrates how to set the key size to 256 bits:
kgen.init(256); // 128 and 192 bits also available
The JCE examples given here show how to use AES for different key sizes, but they don't touch upon the more intricate issues -- like key management or key exchange algorithms. In practice, you may be more likely to use a protocol like Secure Socket Layer (SSL), which negotiates session keys using public keys that are subsequently used for bulk encryption.
Java Secure Socket Extension (JSSE) APIs are based around SSL, and the APIs are responsible for key negotiation and subsequent encryption and decryption. For a sample set of programs that illustrate the use of JSSE, see my earlier articles (listed in the See Also section, below). Since some of these articles are somewhat dated, note that the
trustStore entries will have to replaced by later versions of the corresponding files.
Some of the cipher suites may not be enabled for optimization of startup time. When
SSLSockets are first created, no handshaking is done, so that applications can first set their communication preferences: which cipher suites to use, whether the socket should be in client or server mode, and so on. However, security is always provided by the time that application data is sent over the connection.
getSupportedCipherSuites() method in
SSLSocket returns all the possible suites that can be enabled for the connection. You can then use the
setEnabledCipherSuites() to enable a subset of the available cipher suites, or to prioritize them. Use
getEnabledCipherSuites() to return a list of all the enabled suites that are enabled by default, or that are set by a previous
setEnabledCipherSuites() method call.
You can use the
getCipherSuite() method in
SSLSession to obtain the actual cipher used for the connection.
The following code illustrates the changes I made to the server program. The program uses regular expressions to prioritize AES encryption algorithms, with 256 bits as key size.
Here is the corresponding client code:
When running the server and the client, the output on the server side should be similar to the following:
This output illustrates that the AES 256-bit algorithms are set to higher precedence than the other available algorithms. The cipher suite
TLS_RSA_WITH_AES_256_CBC_SHA name constitutes the key negotiation, bulk encryption algorithms, and the key size, which in this case are RSA, AES and 256, respectively. SHA is used in the HMAC construction for integrity protection. By setting some of the debug output (as illustrated in my earlier article), you can get a peek into the inner workings of the different phases of the SSL algorithm.
Note: For performance reasons, it's probably not a good idea to enable all the supported algorithms, but I've included them here for illustration purposes.
The JCE framework is a very powerful and flexible framework for using different cryptographic algorithms. It's based on a provider architecture that enables the same framework to be used for newer cryptographic algorithms. From a developer perspective, this means a higher level of abstraction, and a common set of APIs for newer and different cryptographic algorithms -- without the need to worry about the inner workings of the algorithm.
Some of the other Java security APIs -- such as JSSE -- are implemented on top of JCE, and supplement it to make the different cryptographic algorithms (ciphers, Message Authentication Codes (MACs), and Key Exchange algorithms) available to in a more developer-friendly manner.
Java World article on AES
Java World article on Java Security optional packages (reprinted in java.sun.com)
AES home page
Raghavan "Rags" Srinivas is a Java technology evangelist at Sun Microsystems, Inc. He specializes in Java technology and distributed systems. Srinivas has worked on several technology areas, including internals of VMS, UNIX® software, and NT.