The Security Class and the Security Manager

Chapter 9. Keys and Certificates

In this chapter, we discuss the classes in the Java security package that handle keys and certificates. Keys are a necessary component of many cryptographic algorithms −− in particular, keys are required to create and verify digital signatures or to perform encryption. Different algorithms require different keys. There are two general types of keys: asymmetric and symmetric. Asymmetric keys come in two types as well, public and private. A public key and a private key are related and are referred to as a key pair. Symmetric keys are also called secret keys. We also cover the implementation of certificates in this chapter. Certificates are used to authenticate public keys; when public keys are transmitted electronically, they are often embedded within certificates. The core Java API comes with the necessary classes to handle public and private keys and their certificates. The classes necessary to handle secret keys come only with JCE. Keys and certificates are normally associated with some person or organization, and the way in which keys are stored, transmitted, and shared is an important topic in the security package. Management of keys is left for the next chapter, however; right now, were just concerned about the APIs that implement keys and certificates. In this chapter, well show how a programmer interacts with keys and certificates as well as how you might implement your own versions of each. The classes and engines we discuss in this chapter are outlined in Figure 9−1. There are two engines that operate on keys: Figure 9−1. The interaction of key classes A generator class creates keys from scratch. With no input or, possibly, input to initialize it to a certain state, the generator can produce one or more keys. Symmetric keys are generated by the KeyGenerator class while asymmetric key pairs are generated by the KeyPairGenerator class. • The KeyFactory class translates between key objects and their external representations, which may be either a byte array or a key specification. • There are a number of classes and interfaces relating to Figure 9−1; in addition to the engine classes themselves, there are several classes and interfaces that represent the key objects and the key specifications the encoded key data is always an array of bytes. In an effort to provide the complete story, well delve into the details of all of these classes; for the most part, however, the important operations that most developers will need are: The ability to create new keys from scratch using the key pair generator or the key generator. • The ability to export a key, either as a parameter specification or as a set of bytes, and the corresponding ability to import that data in order to create a key. • This means that, for the most part, the data objects we explore in this chapter −− the Key classes and interfaces as well as the various KeySpec classes key specification classes −− can be treated by most programmers as opaque objects. Well show their complete interface which you might be curious about and which is absolutely needed if youre writing your own security provider, but well try not to lose sight of the two goals of this chapter.

9.1 Keys

Lets start with the various classes that support the notion of keys within Java.

9.1.1 The Key Interface

The concept of a key is modeled by the Key interface java.security.Key : public interface Key extends Serializable Model the concept of a single key. Because keys must be transferred to and from various entities, all keys must be serializable. As we discussed in Chapter 8, there might be several algorithms available for generating and understanding keys, depending on the particular security providers that are installed in the virtual machine. Hence, the first thing a key needs to be able to tell us is what algorithm generated it: public String getAlgorithm Return a string describing the algorithm used to generate this key; this string should be the name of a standard key generation algorithm. When a key is transferred between two parties, it is usually encoded as a series of bytes; this encoding must follow a format defined for the type of key. Keys are not required to support encoding −− in which case the format of the data transferred between the two parties in a key exchange is either obvious e.g., simply the serialized data of the key or specific to a particular implementation. Keys tell us the format they use for encoding their output with this method: public String getFormat Return a string describing the format of the encoding the key supports. The encoded data of the key itself is produced by this method: public byte[] getEncoded Return the bytes that make up the particular key in the encoding format the key supports. The encoded bytes are the external representation of the key in binary format. Those are the only methods that a key is guaranteed to implement other than methods of the Object class, of course; most implementations of keys override many of those methods. In particular, youll note that there is nothing in the key interface that says anything about decoding a key. Well say more about that later.

9.1.2 Asymmetric Keys

Asymmetric keys are the more popular type of key. These keys come in pairs; hence the core Java API contains these two additional interfaces: public interface PublicKey extends Key 140