The moral of the story is that authentication does not magically solve any problem; it is merely a tool that can be used in the pursuit of solutions.
7.3 Cryptographic Engines
In the next few chapters of this book, were going to see how Java provides an interface to the algorithms required to perform the sort of authentications weve just talked about. Well also explore the architecture Java
provides for general implementation of these algorithms, including ones such as encryption that are not strictly required for authentication. If youre not familiar with the various cryptographic algorithms weve been
alluding to so far in this chapter, the next section should sort that all out for you.
Essentially, all cryptographic operations are structured like the diagram in Figure 7−2. Central to this idea is the cryptographic algorithm itself, which is called an engine; the term algorithm is reserved to refer to
particular implementations of the cryptographic operation. The engine takes some set of input data and optionally some sort of key and produces a set of output data. A few points are relevant to this diagram.
There are engines that do not require a key as part of their input. In addition, not all cryptographic engines produce symmetric output −− that is, its not always the case that the original text can be reconstructed from
the output data. Also, the size of the output is typically not the same as the size of the input. In the case of message digests and digital signatures, the output size is a small, fixed−size number of bytes; in the case of
encryption engines, the output size is typically somewhat larger than the input size.
Figure 7−2. A cryptographic engine for encryption
In the Java security package, there are two standard cryptographic engines: a message digest engine and a digital signature engine. In addition, for some users, an optional engine is available to perform encryption.
Finally, because keys are central to the use of most of these engines, there is a wide set of classes that operate on keys, including engines that can be used to generate certain types of keys. The term engine is also used
within the security package to refer to other classes that support these operations.
7.3.1 Cryptographic Keys
The first engines well look at generate cryptographic keys. Keys are the basis for many cryptographic operations. In its simplest sense, a key is a long string of numbers −− not just any string of numbers, but a
string of numbers that has very strict mathematical properties. The mathematical properties a key must have vary based on the cryptographic algorithms it is going to be used for, but theres an abstract logical set of
properties all keys must have. Its this abstract set of properties that well see in the Java security package.
In the realm of cryptography, keys can either come alone in which case they are called secret keys or in pairs. A key pair has two keys, a public key and a private key. So all together there are three types of keys −−
secret, public, and private.
When an algorithm requires a secret key, both parties using the algorithm will use the same key. Both parties must agree to keep the key secret, lest the security of the cryptography between the parties be compromised.
The secret key approach suffers from two problems. First, it requires a separate key for every pair of parties that need to send encrypted data. If you want to send your encrypted credit card data to ten different Internet
stores, you would need ten different keys. Worse yet, if you operated an Internet store and had millions of customers, you would need literally millions of keys −− one per customer. Management of such keys is a very
difficult problem.
The other problem with this approach is coming up with a method for sharing the keys. Its crucial that the key be kept secret, since anyone with the key can decrypt the data to be shared. Hence, you cant simply send the
key over the network without somehow encrypting the key itself; doing so would be tantamount to sending the data itself unencrypted. There are engines that perform secure secret key exchange, however; these key
exchanges are the basis of many operations, including SSL.
Public and private keys can provide asymmetric operation to cryptographic engines. The public key can be used by one party participating in the algorithm, and the private key can be used by the other party.
The usefulness of this type of key pair is that one key can be published to the world. You can email your public key to your friends and your enemies, you can put it on a global key server somewhere, you can
broadcast it on the Internet −− as long as you dont lose your private key, you can do anything you like with your public key.
Then, when someone wants to send you some sensitive information, they can use your public key to encrypt the data −− and, as long as you have kept your private key private, youll be the only one who is actually able
to decrypt the data. Similarly, when you want to send sensitive data to someone, all you need is their public key; when the data has been encrypted with the public key, you know that only the holder of the private key
will be able to read what youve sent her. In the area of digital signatures, this key ordering is reversed: you sign a document with your private key, and the recipient of the document needs your public key in order to
verify the digital signature.
Public key encryption is not without its key management problems as well, however. When you receive a digitally signed document, you need the public key of the signer of the document. The mechanism to obtain
that key is very fluid; there are a number of proposals for centralized key warehouses that would hold public keys and for methods to access those keys, but the infrastructure to make this all a reality is not really in place.
Hence, users of public keys have adopted a variety of techniques for obtaining the public keys.
7.3.2 Message Digests
The second engines that well examine deal with message digests. A message digest is the digital fingerprint we alluded to earlier. Conceptually, a message digest is a small sequence of bytes that is produced when a
given set of data is passed through the message digest engine. Unlike other cryptographic engines, a message digest engine does not always require a key to operate; some do, and some do not. A message digest engine
takes a single stream of data as its input and produces a single output. We call the output a message digest or simply a digest, or a hash, and we say that the digest represents the input data.
The digest that corresponds to a particular set of data does not reflect any information about that data −− in particular, there is no way to tell from a digest how much data it represents or what the data actually was. A
message digest is useful only when the data it represents is also available. If you want to determine whether a particular digest represents a particular set of data, you must recalculate the digest and compare the newly
calculated digest with the original digest. If the two are equal, youve verified that the original digest does indeed represent the given set of data.
Data that is fed into a message digest engine is always treated as an ordered set of bytes. If even one byte of the data is altered or absent or presented out of order, the digest will be different. Hence, a typical message