Master the basics of Java Cryptography Extension (JCE)
Note that although the JCE is now a core package in Java SDK 1.4, we'll demonstrate how to configure it using Java SDK 1.2 or higher (static installation). Also, I'll cover how to use security providers with no setup at all (dynamic installation). Finally, I'll demonstrate how to create a key and a cipher and how to perform basic data encryption and decryption.
Static installation
Before using or installing JCE, you must first obtain the library from the Sun
Web site. JCE contains
Sun’s own security provider, SunJCE. To statically add SunJCE to your list of
default providers, you need to edit the security properties file:
For instance, if you installed the JDK on a Windows machine in the folder C:\jdk1.3, you'd need to edit this file:
To install the SunJCE, you'd add the following line to the above file:
security.provider.n=com.sun.crypto.provider.SunJCE
Substitute n with the priority for this provider.
Listing A demonstrates how you can view information about installed providers. The output displayed in Listing B shows information the provider supports, such as the available algorithms.
Dynamic installation
Listing C shows how to dynamically load a provider at
runtime. It should be noted that when you invoke Security.addProvider(…),
the provider is available to the entire JVM.
As stated previously, when you install a provider, you provide a number to indicate its priority. When an implementation is called for, the JVM will search through all installed security providers according to their priority and use the first provider it finds that implements the requested algorithm. You can also explicitly call for a given provider by including additional arguments to certain method calls, as we will see later.
Implementation details
The JCE API consists of numerous classes and interfaces for working with several kinds of algorithms and security features. In this first installment, we'll deal with using a popular symmetric algorithm, Data Encryption Standard (DES).
Generating keys
Listing D shows how to initialize a
KeyGenerator and generate a key.
DES/ECB/PKCS5Padding
This provides a DES algorithm, with the Electronic Codebook (ECB) mode and PKCS#5 style padding. A second String parameter can be passed to specify provider implementation to use, but it is not necessary:
KeyGenerator kg = KeyGenerator.getInstance("DES");
Once we have our KeyGenerator, we invoke the generateKey method to get our key:
Key key = kg.generateKey();
Generating a cipher
We generate a cipher in much the same way that we generate a key. We must invoke
the static method getInstance in the Cipher class. The parameters
for this method work exactly as with KeyGenerator:
Cipher cipher = Cipher.getInstance(“DES”);
Listing E shows how to do this.
Encrypting and decrypting data
Encryption works at the byte level, so almost anything can be encrypted. Once
you have a key and a cipher, you're ready to go. It should be noted that the
same algorithm must be used for both the key and cipher. You cannot have a key
initialized with DESede and a cipher initialized with DES. The Cipher
object uses the same methods to encrypt and decrypt data, so you must initialize
it first to let it know what you want done with the data:
cipher.init(Cipher.ENCRYPT_MODE, key);
This call initializes the Cipher object and gets it ready to encrypt data. The simplest way to encrypt data is invoking the doFinal method on the Cipher object passing in a byte array:
byte[] data = “Hello World!”.getBytes();
byte[] result = cipher.doFinal(data);
The result will now contain the encrypted representation of the passed-in data. It's just as easy to decrypt the same data. But before we can do that, we must reinitialize the Cipher object and get it ready for decryption:
cipher.init(Cipher.DECRYPT_MODE, key);
Once we do this, we are ready to decrypt:
byte[] original = cipher.doFinal(result);
Now, original should now be identical to data. See Listing F for the full source code.
Summary
JCE is a powerful API, allowing numerous types of encryption, as well as several other security-related tasks. We've seen how to install the JCE both statically and dynamically, as well as use a symmetric encryption algorithm to encrypt and decrypt a simple message. In part two of this series, we'll take what we have learned in this article and apply it to a real-world scenario. I'll show you how to write a simple wrapper that can be used with sockets to encrypt all network traffic for your applications.