Java Cryptography Architecture
JDK 1.1 introduced the Security API along with the Java Cryptography Architecture (JCA), a framework of classes, interfaces, and packages for developing cryptographic applications and components for the Java platform. The JCA's provider-based architecture allows for heterogeneous cryptography implementations.
JDK 1.2 added additional services such as:
- Keystore creation and management
- Algorithm parameter management
- Algorithm parameter generation
- Key factory support to convert between different key representations.
Sun's version of the JRE includes a default JCA provider package that contains implementations of the MD5 and SHA-1 algorithms, a certificate factory for X.509 certificates and certificate revocation lists, a pseudo-random-number generation algorithm, and a keystore implementation.
The Java Cryptography Extension (JCE) extends the JDK to include APIs for encryption, key exchange, and message authentication code. Together the JCE and the JCA provide a complete, platform-independent cryptography API; however, because the JCE provider included with JDK 1.4.x doesn't support a number of algorithms such as RSA, it's advisable to install a JCE provider that supports a more robust set of algorithms. The sample code
provided with this article uses the BouncyCastle provider
If you are running version 1.4.x of the Java SDK, follow these steps to add a JCE provider to your JDK/JRE environment:
Java Cryptography and Asymmetric Keys
- Download and install a JCE provider JAR file.
- Copy the JCE provider JAR file to your <JAVA_HOME>/jre/lib/ext/ directory.
- Edit the <JAVA_HOME>/jre/lib/security/java.security properties file using a text editor. Add the path to the JCE provider you've just downloaded to this file. You need to add a line complying with the following format, where <n> is the order of precedence to be used by the JRE when evaluating security providers. Make sure that the Sun security provider remains at the highest precedence, with a value of 1.:
- Save and close the file.
The JCE supports symmetric keys via the API classes and interfaces found in the java.security
package. With this package, you can generate a public/private key pair as follows:
- Create an instance of a KeyPairGenerator for the desired algorithm.
- Initialize the KeyPairGenerator instance with the desired number of bits for the key-size.
- Call the generateKeyPair() method to generate the key pair.
In code, the process looks like this:
Java Cryptography and Symmetric Keys
KeyPairGenerator generator =
KeyPair keyPair = generator.generateKeyPair();
The JCE also supports symmetric keys through the API classes and interfaces in the javax.crypto.*
packages. You create a symmetric key in much the same manner as you create a key pair, as follows:
SecretKey key =
Next, you use a factory method of the Cipher class to create a Cipher instance to encrypt and decrypt data.
Cipher cipher = Cipher.getInstance("DES");
At this point, you must call the init()
method to specify which encrypt/decrypt function to perform. Finally, call the doFinal()
method to perform the desired cryptographic function. The following code illustrates initializing a Cipher instance to perform encryption on a byte array of data using a previously generated symmetric key.
byte data = "A simple string".getBytes();
byte encryptedBytes =
In the preceding example, both the encryption and the decryption were performed with the same Key object. But because encryption and decryption ordinarily occur on different VMs at different times, you need a method to transport the key securely.