The word cryptography comes from the Greek words kryptos meaning hidden and graphein meaning writing. Cryptography is the study of hidden writing, or the science of encrypting and decrypting text.
Nineteenth century scholars decrypted ancient Egyptian hieroglyphics when Napoleon's soldiers found the Rosetta Stone in 1799 near Rosetta, Egypt. Its inscription praising King Ptolemy V was in three ancient languages: Demotic, hieroglyphics, and Greek. The scholars who could read ancient Greek, decrypted the other languages by translating the Greek and comparing the three inscriptions.
In the twentieth century world of computer networks, messages are digitally encrypted on the sending side and decrypted on the receiving side using cryptographic services and algorithms. Algorithms are mathematical techniques or rules that apply a cryptographic service to a message. Cryptographic services include hashing a message, encrypting and decrypting a message, and signing or verifying the signature on a message. A message digest object uses a hashing algorithm to make a hash digest of the original message, key pairs use a key algorithm compatible with the hashing algorithm to encrypt and decrypt the message, and a signature object uses the key pairs to sign and verify the signature on a message.
The Java Cryptography Architecture (JCA) framework in the Java Development Kit (JDK) 1.2 provides a full range of cryptographic services and algorithms to keep messages sent over the network secure. The framework is extensible and interoperable. Not only can you add cryptographic service implementations by different vendors to the framework, but, for example, the signature service implementation by one vendor will work seamlessly with the signature service implementation by another vendor as long as both vendors' implementations use the same signature algorithm. Given how implementations can vary from vendor to vendor, the flexibility built into the JCA framework lets you choose an implementation that best meets your application requirements.
You will find additional JCA features in Java Cryptography Extension (JCE) 1.2 in a separate download (JDK 1.2 is required). JCE 1.2 provides ciphers (symmetric, asymmetric, block, and stream), secure Java streams, and key generation. JCE 1.2 features are not covered in this article.
Cryptographic services include message digests, encryption keys, digital signatures, and algorithm parameters.
A message digest is a unique and reliable hash of the message that lets the receiver know that the message received is the exact same message that was sent. Every message digest is unique and in no way reveals anything about the message contents. On the sending side, the digest is calculated and sent with the message. On the receiving side, the message hash is calculated again and compared with the hash received with the message. If the two hashes are the same, it is very unlikely the message was altered on its way to its destination.
In JDK 1.2 the
class subclasses from the
MessageDigestSpi class for backwards
compatibility with JDK 1.1.
An encryption key is a secret value used to encrypt and decrypt messages or hashes. The key value is known only to the sender and receiver of the data. When data is encrypted, the key algorithm transforms the original data to cipher text, and when the data is decrypted, the key algorithm transforms the cipher text to original text. In the diagram, the message is hashed and the hash encrypted. The message could be encrypted too, but is not in this case because the contents of the message are not private. The hash is encrypted so the receiving side can verify the message arrived without being altered on its way.
Data is encrypted an decrypted with public and private key pairs. The private key is kept secret and public key is generally available. The keys in the pair have a mathematical relationship, so if you encrypt data with your own private key, the recipient of the data can decrypt it with your public key. Likewise, anyone can send another person data encrypted with the recipient's public key, which the recipient decrypts with the private key. On the sending side, the data is encrypted with a key and remains inaccessible to anyone on the receiving side who does not have the other key in the pair to decrypt the data.
Sometimes certificates are used with keys. A certificate is a digitally
signed statement from a third-party saying the public key of another
party has a particular value. A certificate guards against the possibility
that the encryption key value has been illicitly changed. JDK 1.2. adds the
java.security.cert package so you can create different types of
certificates and manage lists of revoked certificates.
The algorithm in use and secrecy of the private key determine the effectiveness of the key encryption, or how hard it is to break the encrypted message. The JCA framework provides classes that let you obtain keys in the following ways:
Keys are stored in the
keystore database, which is a file-based repository
for keys and certificates. JDK 1.2 provides Key Tool to manage the key pairs and
certificates in the keystore database, and the
KeyStore class for
developers who want to create a custom keystore database.
A digital signature is added to the encrypted data after the data is key encrypted to indicate exactly who sent the data and who is to receive it. On the sending side, the data is signed, and on the receiving side, the signature on the data is verified. If the verification succeeds, it is very likely the sender and receiver are who they are supposed to be. In the diagram, the hash is key encrypted and signed so the receiving side can verify the signature on the hash. The message could also be signed if needed or desired.
In JDK 1.2 the
class subclasses from the
SignatureSpi class for backwards
Algorithms are created from values or algorithm parameters. For example, the Digital Signal Algorithm (DSA) consists of the parameters P, Q, and G. The DSA specification for a private key consists of key X and parameters P, Q, and G, and the DSA specification for a public key consists of key Y and parameters P, Q, and G. In JDK 1.2, you can access algorithm parameters, get the algorithm name and encoding format associated with a parameter set, and generate the parameters for a specified algorithm.
Providers use algorithm parameters to implement
an algorithm-independent key initialization for a key service.
Programmers can use algorithm parameters with the
class to generate a public or private key.
A provider is a package or set of packages by some vendor that implement cryptographic services. When you request a cryptographic service in your code, you have two options: Specify the desired algorithm and let the framework search the available providers according to a preset preference order, or specify the algorithm and provider. The JCA framework application programming interfaces (APIs) let you query the installed providers and algorithms.
The JCA framework has one default provider package, SUN. This package contains the following:
Signatureclass with the Digital Signal Algorithm (DSA) NIST FIPS 186.
MessageDigestclass with the Message Digest (MD5) RFC 1321 and Secure Hash Algorithm (SHA-1) NIST FIPS 180-1 message digest algorithms.
KeyFactoryclass with DSA and bidirectional conversions between a key representation that provides direct access to algorithm parameters (transparent representation).
You can use the default provider package, install and use provider packages by other vendors, or create and use your own provider package. Implementations by different providers can exchange keys and verify each other's signatures as long as all provider-package implementations keep to the general design pattern inherent in the JCA interfaces and classes.
All you do is subclass the
java.security.Provider class and implement the
cryptographic services you want with the algorithms you need.
A new provider must be installed and configured before it can be used in code.
Here is a list of JCE 1.2 Cryptographic Service Providers.
The following code creates a message digest object, supplies the message
data in three arbitrarily sized byte arrays, and calculates the digest,
which has a fixed size. The
MessageDigest.getInstance string input
specifies the Secure Hash Algorithm (SHA-1) as defined in Secure Hash
Standard, NIST FIPS 180-1. This is a message digest algorithm that
outputs a 160 bit hash. The provider is not specified.
MessageDigest sha = MessageDigest.getInstance("SHA-1") sha.update(inputOne); sha.update(inputTwo); byte hash = sha.digest(inputThree);
This code creates, initializes, and generates an algorithm-independent public and private key pair using the DSA algorithm as defined in Digital Signal Standard, NIST FIPS 186. This algorithm defines a digital signature algorithm that uses the RawDSA asymmetric transformation with the SHA-1 message digest algorithm.
The key has a 1024-bit modulus length and a user-derived random seed. The provider is not specified. A long modulus length with a random number makes the encryption stronger and the cipher text harder to break.
Algorithm-dependent key pair generation is possible by passing
algorithm parameters to the
KeyGen.initialize method in place
of the modulus length. The modulus length is one of the
algorithm parameters passed.
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA"); KeyGen.initialize(1024, new SecureRandom(userSeed)); KeyPair pair = KeyGen.generateKeyPair();
This code creates a
Signature object, initializes it with
the private key generated above, and signs the message.
Signature dsa = Signature.getInstance("DSA"); PrivateKey priv = pair.getPrivate(); dsa.initSign(priv); dsa.update(data); byte sig = dsa.sign();
This code verifies the signature on the data that was signed using the public key generated in the key pair generation example above.
air.getPublic(); dsa.initVerify(pub); dsa.update(data); boolean verifies = dsa.verify(sig); System.out.println("signature verifies: " + verifies);
The JCA framework gives you a full range of cryptographic services that are flexible and easy to use. Each service can be used alone or in combination with one or more other services to create the level of cryptographic security you need.
You can request a cryptographic service by specifying the algorithm you want and let the framework find the provider, or specify the algorithm and provider you want. It is easy to add new provider packages so you readily have the service and algorithm implementations that work best for your application requirements.
See the JDK 1.2 security features article for information on the new JDK 1.2 security features and tools as they apply to end users and system administrators.
© 1994-2005 Sun Microsystems, Inc.