Articles Index
JavaTM 2 Cryptography Extension:
Encrypting and Decrypting Data
Monica Pawlan
Exploring everything from invisible ink to sophisticated digital algorithms,
human beings are constantly seeking new and better ways to safely transfer
secret information from one person to another. Whether the secret is
exchanged between school children, businesses, or governments, the sender
uses some type of cipher to make the messsage unintelligible to
all but the intended recipient.
Encryption and decryption are done using a cipher. A cipher is an object
that carries out encryption and decryption according to an encryption
scheme or algorithm. When encrypting, a cipher produces data called
cipher text, and when decrypting, a cipher produces data called
plain text. An interesting example of data encryption in American
history is the altered Navajo language used for intelligence communications
by the
Navajo
Code Talkers during World War II.
Navajo Code Talkers were Native American marines who altered the sounds in
their spoken language to make it harder to learn than the original language,
which was already very hard to learn. The language cipher they developed was
so complex it could not be understood even by native Navajo speakers.
The Code Talkers used their altered language to radio information about the
movements of Japanese and American troops fighting for control of the Pacific
Islands during World War II. The altered language completely confused the
Japanese troops who were adept at breaking codes and imitating American
marines. Historians believe the Code Talkers were critical in tipping the
balance to an American victory in the Pacific Islands.
The Storm Pattern Navajo rug above
exemplifies the agile, intricate, and
sophisticated mind of the Navajo indian. While today's digital encryption
algorithms are very different from what the Navajo Code Talkers used, the
goal is the same--a way to encrypt and decrypt secret information so it can
be safely transferred from one point to another. Click on the image to see
more Navajo rugs on Steve Getzwiller's
Classic and Contemporary Amerind Art
site.
Cryptographic Features
The JavaTM platform provides two sources
for 1.2 cryptographic features: the java.security package that
comes with the JavaTM 2 platform, and
the supplemental javax.crypto package that comes with the JCE
1.2 standard extension.
The 1.2 cryptographic features are divided between the Java 2 platform
and the JCE 1.2 standard extension so functionality that cannot be exported
outside the United States or Canada is in a separate download from Java 2
platform. However, JCE
1.2 requires Java 2 platform.
java.security
Exportable
|
javax.crypto
Not Exportable
|
|
Message Digests |
Data Encryption |
|
Asymmetric Key Generation |
Symmetric Key Generation |
|
Digital Signatures |
Key Agreement |
|
Algorithm Parameters |
Message Authentication Code |
This article describes the classes in the JCE 1.2 javax.crypto
package. You can find information on the classes in the Java 2
java.security package in the JDC article:
Cryptography:
The Ancient Art of Secret Messages.
JCE 1.2 Classes
The javax.crypto package contains classes for encryption and
decryption, establishing key agreements, and using message authentication
codes. This article focuses on the most commonly used cryptographic
features--encryption and decryption.
Data Encryption
Making plain text into cipher text (unreadable text) is known as
encryption, and making cipher text into plain text is known as
decryption. The javax.crypto package lets you encrypt
and decrypt data in one step, multiple steps, in streams, or in
a sealed object. All approaches require a Cipher
object initialized for either the encryption or decryption operation.
javax.crypto.Cipher
javax.crypto.CipherInputStream
javax.crypto.CipherOutputStream
javax.crypto.SealedObject
Symmetric Keys
Data is encrypted and decrypted with a key. There are two types of
cryptography: Secret-key or symmetric cryptography, and public-key
or asymmetric cryptography. JCE 1.2 supports both types of encryption.
It provides the functionality to generate symmetric session keys for
symmetric encryption, and leverage the KeyPairGenerator
class in the Java 2 platform for the creation of asymmetric key pairs for asymmetric
encryption.
Symmetric key cryptography uses a single key to encrypt and decrypt a
message. If someone uses a single key to encrypt a message he or she must
find a secure means of transmitting the key to the receiver for decryption.
You can protect a secret key by wrapping it under the public key(s) of its
intended recipient(s) so only the intended recipient(s) can unwrap it using
their corresponding private key(s). An alternative way to share a secret
key is by using a key agreement. A key agreement is a process used by two
or more parties to agree upon a shared secret key without exchanging any
secret information.
javax.crypto.KeyGenerator
javax.crypto.SecretKey
javax.crypto.SecretKeyFactory
javax.crypto.MAC
javax.crypto.KeyAgreement
Note:
Asymmetic key cryptography uses key pairs that consist of a
public and private key where the private key is mathematically
linked to the public key. Asymmetric keys are generated with
the java.security.KeyPairGenerator class.
Examples
The Cipher and KeyGenerator classes are central
to data encryption and decryption. The following pseudo code segments outline
how you would use these and other javax.crypto classes to encrypt
and decrypt a short text string.
Note:
Crytography software is not exportable outside the U.S.
and Canada, which is why the examples in this section
are pseudo code rather than source code.
Using Ciphers and Sealed Objects
The pseudo code segments for both examples assume two programs: an
encryption program and a decryption program. The encryption program
uses a secret key to encrypt a text string and a sealed object to wrap
the secret key with the recipient's public key. The decryption program
receives the encrypted text and wrapped session key over the network.
It unwraps the secret key by using its private key, and uses the
recovered secret key to decrypt the message.
The SealedObject class can be used to seal any object that
is serializable (implements the java.io.Serializable interface).
One of the arguments to the SealedObject constructor is the
object to be sealed, whose contents are serialized and encrypted. The
SealedObject instance encapsulates those contents. The encrypted
contents are later unsealed and de-serialized to yield the original object.
Encryption Side
The main method creates a Cipher object
and SecretKey. Next, the generated session key is used
to initialize the Cipher object for encryption, and the
Cipher object is used to encrypt the message. The session
key is sealed with the intended recipient's public key and sent to the
intended recipient with the encrypted message.
public static void main(String[] args) {
Create a Cipher object for symmetric
encryption (e.g., DES)
Create a KeyGenerator object
Use KeyGenerator to create a Secret (
session) key
Initialize Cipher object for encryption
with session key
Encrypt message
Get intended recipient's public key (
e.g., from the
recipient's public key certificate)
Create Cipher for asymmetric encryption (
e.g., RSA), and
initialize it for encryption with
recipient's public key
Create SealedObject to seal session key using
asymmetric Cipher
Serialize SealedObject
Send encrypted message and serialized
SealedObject to intended recipient
}
Decryption Side
The decryption application runs the following pseudo=code:
public static void main(String[] args) {
Receive encrypted message and serialized SealedObject
Deserialize SealedObject
Create asymmetric Cipher object, and initialize it for
decryption with private key (corresponding
to public Key used by the encryption application)
Unseal the wrapped session key using
the asymmetric Cipher
Create symmetric Cipher object (using the same
algorithm that was used by the encryption application)
Initialize symmetric Cipher for decryption with the
recovered session key
Decrypt message
}
Secure Streams
JCE 1.2 provides secure input and output stream functionality
with the javax.crypto.CipherInputStream and
javax.crypto.CipherOutputStream classes.
These classes are a FilterInputStream or
FilterOutputStream, respectively, and use
a Cipher object to encrypt or decrypt the
data passing through.
A program uses the javax.crypto.CipherInputStream class to
read a stream of data in and encrypt or decrypt it before returning the
data to the program, and a javax.crypto.CipherOutputStream
to encrypt or decrypt a stream of data before writing it out.
For example, if you want to store some data in encrypted format to a file,
you would create a FileOutputStream and Cipher
object, initialize the Cipher object for encryption, and create
a CipherOutputStream using the FileOutputStream
and Cipher objects. The write method of
CipherOutputStream will encrypt the data passed
through it before writing them out to the file.
To read the encrypted data from the file, you would create
FileInputStream and Cipher objects,
initialize the Cipher object for decryption with
the appropriate key, and create a CipherInputStream
object from the FileInputStream and Cipher
objects. The read method of CipherInputStream
reads the data from the file and decrypts them before returning them
to the application.
Conclusion
The java.security and javax.crypto packages
provide the functionality you need for secure network communications.
This article introduces you to the most commonly used cryptographic
features. Topics not covered include getting algorithm parameters, the
KeyAgreement class, the MAC class for Message
Authentication Codes, and installing providers.
You can find more information in the following documents:
Monica Pawlan
is a staff writer on the JDC team.
She has a background in 2D and 3D graphics, security, database
products, and loves to explore emerging technologies.
monica.pawlan@eng.sun.com
Reader Feedback
Tell us what you think of this article.