Exploring everything from invisible ink to sophisticated digital algorithms, human beings are constantly seeking 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 message 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.
The Java platform provides two sources
for cryptographic features: the java.security package that
comes with the Java 2 platform, and
the supplemental javax.crypto package that comes with the JCE
standard extension.
The cryptographic features are divided between the Java 2 platform and the JCE 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 requires Java 2 platform.
java.securityExportable |
javax.cryptoNot 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 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.
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.
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.Cipherjavax.crypto.CipherInputStreamjavax.crypto.CipherOutputStreamjavax.crypto.SealedObject
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 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.KeyGeneratorjavax.crypto.SecretKeyjavax.crypto.SecretKeyFactoryjavax.crypto.MACjavax.crypto.KeyAgreementNote:
Asymmetric 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 thejava.security.KeyPairGeneratorclass.
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: Cryptography 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.
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 deserialized to yield the original object.
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
}
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
}
JCE 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.
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:
© 1994-2005 Sun Microsystems, Inc.