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 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) in a separate download. JCE provides ciphers (symmetric, asymmetric, block, and stream), secure Java streams, and key generation. JCE 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 the MessageDigest
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. The
java.security.cert
package enables you to 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:
KeyGenerator
class.keyFactory
class.
Keys are stored in the keystore
database, which is a file-based repository
for keys and certificates. The Key Tool enables you 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.
The Signature
class subclasses from the SignatureSpi
class for backwards
compatibility.
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. 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 Keyfactory
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:
Signature
class with the Digital Signal Algorithm (DSA) NIST FIPS 186.MessageDigest
class with the Message Digest (MD5) RFC 1321 and Secure Hash Algorithm (SHA-1) NIST FIPS 180-1 message digest algorithms.KeyFactory
class 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 provider must be installed and configured before it can be used in code.
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 provider packages so you readily have the service and algorithm implementations that work best for your application requirements.
See the security features article for information on the security features and tools as they apply to end users and system administrators.
© 1994-2005 Sun Microsystems, Inc.