Home | Articles

Cryptography: The Ancient Art of Secret Messages

Rosetta Stone 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.

JCA Cryptographic Services

Cryptographic services include message digests, encryption keys, digital signatures, and algorithm parameters.

How encrypting
data flows through the different stages

Message Digests:

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.

Encryption Keys:

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:

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.

Digital Signatures:

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.

Algorithm Parameters

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.

Providers

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.

Default Provider Package:

The JCA framework has one default provider package, SUN. This package contains the following:

Adding New Provider Packages:

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.

Calculating a Message Digest Object

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);

Generating Key Pairs

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();

Signing Messages and Verifying Signatures

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);

Conclusion

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.

Related Links

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.