CONTENTS

Programming with Cryptographic Libraries: JCE

1. JCE: Java Cryptography Extension.  Java Cryptography has long been used by many programmers, however, it is used as an external package and requires extensive integrity checks on any piece of code.  Recently, Sun Microsystem, the creator of Java, has released a new cryptographic packages that are included with Java 2 Standard Edition version 1.4 (J2SE v1.4). The packages are called Java Cryptography Extension (JCE). It has been widely used from small Java applications such as an Applet to large applications such as Web-based Automating Toolkit. In the current release, JCE has decent APIs that are easy to use.  Also in this release, many new ciphers such as AES have been integrated. For more information about JCE.  You can visit Sun's website for more information on JCE at http://java.sun.com/products/jce/.

2. Overview of JCE.  JCE is composed of many classes, which you can review when you want to use them.  However, there are a few core classes you should know. 

The Cipher class.  This is the core class that is required in every cryptographic program. The Cipher object defines what cipher will be used, the mode that will be used, and what padding method will be used when one is required.  You have to include an initiation, which is used to specify whether the cipher is for encryption or decryption and what parameters are required.  For example, it is required to specify the Initial Vector (IV) when you want to use it in Cipher Block Chaining (CBC) mode.  If you use RC5 cipher, you also need to specify the key size, the input block size, and the operational rounds for encryption.  The parameters are encapsulated in the AlgorithmParameters class. In some special cases, you will need to pass the parameters required for decryption so that the ciphertext can be correctly decrypted.

To do any cipher operation, you need to perform three.  First, you need to initialize the cipher as described above. Then, you need to use update() to run the cipher.  Finally, you need to use doFinal() to complete the cipher process.  However, in JCE, you can use doFinal(plaintext) in most cases, which does not require the use of update().

The Cipher Stream classes.  The cipher stream classes are CipherInputStream and CipherOutputStream. These classes are filter classes that are used in conjunction with FileInputStream and FileOutputStream classes. They encrypt the data stream providing confidentiality.  This class can be used with file encryption or socket applications.

The KeyGenerator and KeyFactory Classes.  The KeyGenerator class is used to generate a set of keys from a specific random number. However, to generate a random number that is secure, you ought to use SecureRandom class to generate a secure random number and use it to generate a key. The KeyFactory Class is used to store secret keys. It provides an abstract level for key storage.

The KeyAgreement Class.  This class provides methods for key agreement protocol such as the Diffie-Hellman protocol. The agreement is composed of exchanging phases. Then, a shared secret or key can be generated after the exchanging phrases.

The Mac Class.  This class is the core class for Message Authentication Code (MAC). Similar to Cipher class, the Mac class is initialized to specify what MAC algorithm and key that should be used. Then, it computes the MAC based on operations such as update(), doFinal() similar to Cipher class methods.

3. JCE Programming.  This section will introduce you to some JCE APIs through the use of an example, which will be encrypting a "Hello World" program.  You will be given sample code that will demonstrate how the JCE works, which can be found below.

First you will load some Java packages including Java security and Java crypto packages, which is done in line 1 - 4. 

1 import java.security.*;
2 import javax.crypto.*;
3 import javax.crypto.spec.*;
4 import java.io.*;

On line 7, you need to specify the exception that will be thrown.  On line 8-10 parameters are defined. 

5 public class hello {
6
7       public static void main(String[] args) throws Exception {
8       String plaintext = "Hello World!";
9       String mykey = "1122334455667788"; // needed to be exactly 16 bytes
10     String myiv = "0123456789abcdef"; // must be 16 bytes for AES
11

On line 13 a key is being defined using the SecretKeySpec class along with the algorithm that the key will be used for.   Line 15 the IV is being definede since AES is being used in CBC mode.  The JCE requires the IV to be exactly 16 bytes long. 

12     // define a key
13     SecretKeySpec keyspec = new SecretKeySpec(mykey.getBytes(), "AES");
14     // define the IV
15     IvParameterSpec ivspec = new IvParameterSpec(myiv.getBytes());

Next the cipher will be instantiated, where you have to specify the cipher type, cipher mode, and the padding mode used.  This is done on line 17.  The backslash (/) is being used to specify these arguments in one string.  This example uses AES in CBC mode with a PKCS#5 padding mode.  There are a number of ciphers that are available to be used along with modes and padding methods that can be reviewed at the end of this section. 

16     // set the cipher to desired operations
17     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

The init() method is used  to set the mode for encryption or decryption, key, and the IV, which can be seen in line 19. 

18     // initiate the cipher
19     cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);

In line 21 the plaintext is being encrypted using the doFinal() method.  If you want to handle multiple encryptions you should use the update() method to encrypt one block of data, and then use the doFinal() method to encrypt the remaining data.  The doFinal() method will pad the data it is is less than the specified block size.  The encryption process requires input and output to be in the form of a byte. 

20     // Encrypt
21     byte [] encrypted = cipher.doFinal(plaintext.getBytes());
22

To make encrypted text readable, you will use Base64 encoding, which is done in line 24.  This process is done by using the Base64Encoder class to encode the encrypted bytes.  In line 25 the encoded bytes are being printed out to the screen.   

23     // Encode
24     String encoded = new sun.misc.BASE64Encoder().encode(encrypted);
25     System.out.println(encoded);
26

After encrypting and encoding the data it must be decoded and decrypted.  Line 28 decodes the data, where the Base64Decoder class is being used and returns the bytes it decodes. 

27     // Decode
28     byte [] decoded = new sun.misc.BASE64Decoder().decodeBuffer(encoded);
29

Now you can decrypt the data, which requires you to have the same algorithm parameters that were used for the encryption.  You can use the getParameters() method to retrieve the parameters from the AlgorithmParameters class that holds them.  This is done in line 31.  Line 32 the parameters are printed out to verify their correctness.  In this example CBC is being used so the only parameter that is used is the IV 

30     // get algorithm parameters for decryption
31     AlgorithmParameters aparam = cipher.getParameters();
32     System.out.println("Params " + aparam.toString());
33

After you have gotten the parameters the cipher can be instantiated, which is done in line 35.  The ciphertext can now be decrypted using the doFinal() method as you can see in line 36.  Line 37 the plaintext is being printed out. 

34     // Decrypt using the same key
35     cipher.init(Cipher.DECRYPT_MODE, keyspec, aparam);
36     byte [] decrypted = cipher.doFinal(decoded);
37     System.out.println(new String(decrypted));
38     } // end of main
39 } // end of class

4. Available Ciphers and their defaults.  The following is a list of available ciphers and their default key size and block size. 
 
Cipher Default Key Size Default Block Size
AES 128 bits 128 bits
Blowfish 56 bits 64 bits
DES 56 bits 64 bits
DESede 112 bits 64 bits
PBEWith <digest> and <encryption> Variable due to encryption type Variable due to encryption type
RC2, RC4, and RC5 128 bits 64 bits
RSA 1024 bits Variable


5. Available Modes.  The following is a list of available modes that are available. 
 
Mode Description
NONE No mode is used
CBC Cipher block chaining mode
ECB Electronic code book mode
CFB Cipher feedback mode
OFB Output feedback mode
PCBC Propagating CBC mode defined by Kerberos v4

6. Available Padding Methods.  The following is a list of available padding methods.   
 
Pad Method Description
NoPadding No padding is used, requiring the data's length to be the size of multiple blocks
OAEPWith <digest> and <mgf> Padding Use RSA OAEP padding
PKCS5 Padding PKCS # 5 standard padding
SSL3 Padding Use SSL v 3 padding (not available with J2SE v1.4)

For more Java programming libraries, there are plenty of on-line resources and books. Please see the Resources section at the end of the document.