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.
|