Java Cryptography Extensions (JCE) provide a framework and implementation for encryption, key generation, and authentication algorithms. Encryption support includes asymmetric, symmetric, block, and stream ciphers. These extensions also support secure streams and sealed objects. JCE is part of the Java 2 SDK version 1.4 and was an optional package in earlier JDKs. It is contained in the javax.crypto package.
The principle behind the Java Cryptography Extensions is to provide an API that allows pluggable algorithms and implementations, using provider architecture. The framework can use providers signed by a trusted entity. This also allows algorithms that have not yet been created to be inserted in the future.
The base JDK comes with the SunJCE provider and provides support for the following services:
DES and Triple DES
Cipher Block Chaining (CBC) and Propagating Cipher Block Chaining (PCBC)
Cipher Feedback (CFB) and Output Feedback (OFB)
MD5 and SHA1 hashes
MD5 with DES Cipher Block Chaining password-based encryption as defined in PKCS #5
A Diffie-Hellman key pair generator used to generate a pair of public and private values
A key store implementation for the proprietary key store type named "JCEKS"
Let's look at a simplistic example of using the Java Cryptography Extensions to generate a one-way hash using the MD5 algorithm:
import java.security.*; // Use the MD5 Algorithm MessageDigest md = MessageDigest.getInstance("MD5"); // Take message and convert to bytes byte buf[] = Message.getBytes(); // Populate the buffer with the message md.update(buf); // Create the digest byte digestBuf[] = md.digest();
In this scenario, if the message varies, so will the digest, as Table 15.5 shows. JCE also generates reversible encryption. Lets look at an example that uses the Blowfish algorithm:
import java.security.*; import javax.crypto.*; // Get a cryptography provider Provider sunJce = new com.sun.crypto.provider.SunJCE(); // Obtain an instance of the Blowfish cipher Cipher c = Cipher.getInstance("Blowfish"); // Obtain an instance of a key generator KeyGenerator kg = KeyGenerator.getInstance("Blowfish"); // Generate the key specification SecretKey sk = kg.generateKey(); byte[] raw = sk.getEncoded(); SecretKeySpec ks = new SecretKeySpec(raw, "Blowfish"); // Initialize the cipher using the key specification cipher.init(Cipher.ENCRYPT_MODE, ks); // Update the buffers while (msg[ii] != null) enc = cipher.update(msg[ii].getBytes()); // Finish processing enc = cipher.doFinal();
Message |
MD5 Digest |
---|---|
I need a raise of $10,000. |
9i5nud5r2a9idskjs2tbuop2ildax |
I need a raise of $100,000. |
8m4ikijuelaidsfg8asyfnasdfgl1 |
I need a raise of $1,000,000. |
4M9i2t8c7h436l712t1h4e1d1otg7 |
You should notice that the first thing we did was obtain a reference to a cryptographic provider. This mechanism allows you to plug in at will other third-party providers approved by Sun. Additionally, the providers themselves cannot be used as standalones and will work only in the context of the JCE framework.
Export restrictions on the use of certain encryption algorithms is controlled by jurisdiction policy files of JCE. These policy files are typically stored under the java-home directory in lib/security. A supplemental version of JCE is available that allows for "unlimited strength" algorithms for those living in eligible countries. The download URL is available at http://java.sun.com/products/jce/index-14.html.
The implementation of JCE as of JDK 1.4 is feature rich and provides many methods to make your application secure. Let us look at a small subset of some of the classes that are part of the package:
Cipher. Provides a cryptographic cipher for use in encryption and decryption.
CipherStream. Combines an InputStream or OutputStream with a cipher object. Secure streams are provided by CipherInputStream and CipherOutputStream classes.
CipherInputStream. Represents a secure input stream into which a cipher object has been interposed. It is derived from java.io.FilterInputStream.
CipherOutputStream. Represents a secure output stream into which a cipher object has been interposed. It is derived from java.io.FilterOutputStream.
KeyGenerator. Used to generate secret keys for symmetric algorithms.
SecretKeyFactory. Represents a factory for creating secret keys.
SealedObject. Enables a developer to create an object and protect its confidentiality with a cryptographic algorithm. This is useful when you want to encapsulate a serializable object using an algorithm such as DES, to protect its confidentiality. The encrypted content can be decrypted and deserialized to produce the original object.
KeyAgreement. Provides the functionality of a key agreement protocol. Using one of the key generators (KeyPairGenerator or KeyGenerator), the resulting keys are used to establish a shared secret.
MAC. Responsible for creating a Message Authentication Code object.
Provider. Contains the interface to the concrete implementation of the Java 2 SDK security API features.
Security. Manages installed providers and security-wide properties. This class is never instantiated and contains only static methods. Only Trusted programs can execute it.
MessageDigest. Provides secure message digests, such as SHA1 or MD5.
Signature. Provides a digital signature implementation, such as DSA or RSA with MD5. It takes an arbitrary-sized input and a private key and generates a relatively short string of bytes, known as the signature. Given the public key corresponding to the private key used to generate the signature, you can validate the authenticity and integrity of the input.
The default keystore in JDK 1.4 is the Sun provider. JCE provides its own implementation of java.security.KeyStore and is referred to as "SunJCE." The SunJCE keystore uses a password-based encryption along with Triple DES for protection of private keys. To use the special implementation of the JCE keystore, you can specify "JCEKS" as the keystore type.