Symmetric Encryption
91
When constructing the sealed object, we need to use a fully initialized cipher. When decrypting, we can use
either a cipher or just the key, and the sealed object will remember the settings for the cipher used to
encrypt the object. Let's try an example of sealing an object with a DESede key. This example doesn't
really do anything interesting externally, but rather simply expresses the syntax of using a SealedObject
to seal a String object:
import java.io.*;
import javax.crypto.*;
import java.security.*;
public class SealedObjectExample
{
public static void main (String[] args)
throws Exception
{
String creditCard = "1234567890";
KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
System.out.println("Creating a key.");
Key key = keyGenerator.generateKey();
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.ENCRYPT_MODE, key);
System.out.println("Encrypting the object.");
SealedObject so = new SealedObject(creditCard, cipher);
System.out.println("Unencrypting the object.");
String unencryptedCreditCard = (String)so.getObject(key);
System.out.println("Credit card number: "+unencryptedCreditCard);
}
}
There is a bug, err, feature in the JDK1.2 that prevents extensions from using the class loader to create
classes that are neither standard objects nor extensions. This means that if we create a custom object, say, a
CreditCard object, as opposed to a simple String, we won't be able to decrypt it. Instead, we'll need to
build our own implementation of SealedObject to accomplish that.
We've written an EncryptedObject class to do exactly that. It's functionally equivalent to
SealedObject, but can be used with custom classes. We just need to have it in our classpath to use it. It's
called EncryptedObject to avoid namespace collision with SealedObject, but they are otherwise
identical, and you can use this EncryptedObject class as a drop-in replacement for SealedObject
because its method signatures are exactly the same. It is provided for you in Appendix D of this book.
Summary
Symmetric encryption is a valuable tool for security. It provides us with the ability to hide data from prying
eyes in various formats. Symmetric-key encryption has one big problem though: key distribution. In order
to send encrypted messages to someone, we need to share a key with them. As we demonstrated in Chapter
3 with our Hamlet examples, this can be very difficult to do properly. In essence, we need to have a shared
secret at some point in order to share secret messages in the future.
What's really needed is some way to bootstrap the process, some way to create a shared secret by
exchanging purely public information. Asymmetric-key encryption, or public-key encryption does exactly
that. In the next chapter, we'll show how to incorporate public-key encryption into our Java programs.