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.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 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.Cipher
javax.crypto.CipherInputStream
javax.crypto.CipherOutputStream
javax.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.KeyGenerator
javax.crypto.SecretKey
javax.crypto.SecretKeyFactory
javax.crypto.MAC
javax.crypto.KeyAgreement
Note:
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.KeyPairGenerator
class.
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.