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
public interface PrivateKey extends Key
These interfaces contain no additional methods; they are used simply for type convenience. A class that implements the PublicKey interface identifies itself as a public key, but it contains no public methods different from any other key.
The security providers that come with Sun's implementation of Java provide two types of asymmetric keys:
DSA and RSA. JCE provides an additional type of asymmetric key: Diffie−Hellman. Each of these have their own interface that allows you to determine fundamental information about the key. For most programmers, however, keys are opaque objects, and the algorithm−specific features of keys are not needed (except in certain cases when you need to transfer keys).
9.1.2.1 DSA keys
These interfaces allow you to retrieve the DSA algorithm−specific parameters P, Q, and G that are used to generate the keys. Knowledge of these variables is abstracted into the DSAParams interface
(java.security.interfaces.DSAParams):
public interface DSAParams {
public BigInteger getP( );
public BigInteger getQ( );
public BigInteger getG( );
}
Keys that are generated by DSA will typically implement the DSAKey interface (java.security.interfaces.DSAKey):
public interface DSAKey
Provide DSA−specific information about a key.
Implementing this interface serves two purposes. First, it allows the programmer to determine if the key is a DSA key by checking its type. The second purpose is to allow the programmer to access the DSA parameters using this method in the DSAKey interface:
public DSAParams getParams( )
Return the DSA parameters associated with this key.
These methods and interfaces allow us to do specific key manipulation like this:
public void printKey(Key k) { if (k instanceof DSAKey) {
System.out.println("key is DSA");
System.out.println("P value is " +
((DSAKey) k).getParams().getP( ));
}
else System.out.println("key is not DSA");
}
The idea of a DSA key is extended even further by these two interfaces (both of which are in the java.security.interfaces package):
public interface DSAPrivateKey extends DSAKey public interface DSAPublicKey extends DSAKey
These interfaces allow the programmer to retrieve the additional key−specific values (known as Y for public keys and X for private keys in the DSA algorithm):
public void printKey(DSAKey k) { if (k instanceof DSAPublicKey)
System.out.println("Public key value is " +
((DSAPublicKey) k).getY( ));
else if (k instanceof DSAPrivateKey)
System.out.println("Private key value is " +
((DSAPrivateKey) k).getX( ));
else System.out.println("Bad key implementation");
}
DSA keys are often used in the Java world (and elsewhere in cryptography), and if you know you're dealing with DSA keys, these interfaces can be very useful. In particular, if you're writing a security provider that provides an implementation of DSA keys, you should ensure that you implement all of these interfaces correctly.
9.1.2.2 RSA keys
Unlike their DSA counterparts, RSA keys do not share a common type. However, the following interfaces exist for particular RSA keys (within the java.security.interfaces package):
public interface RSAPrivateKey extends PrivateKey public interface RSAPrivateKeyCrt extends RSAPrivateKey public interface RSAPublicKey extends PublicKey
These interfaces define keys suitable for use in RSA algorithms.
These interfaces allow you to retrieve the parameters used to create the RSA key. In particular, the RSA public key interface has methods to return its modulus and public exponent while the private key has methods to return its modulus and private exponent. The RSAPrivateKeyCrt interface defines additional methods to return its prime values (known as P and Q) and their exponents.
9.1.2.3 Diffie−Hellman keys
Diffie−Hellman keys are used in secret key agreement, a topic we address in the next chapter. That algorithm is available only within JCE, and Diffie−Hellman key interfaces are defined in the
javax.crypto.interfaces package:
public interface DHKey
public interface DHPublicKey extends DHKey, PublicKey public interface DHPrivateKey extends DHKey, PrivateKey
This set of interfaces defines keys suitable for use in Diffie−Hellman algorithms.
Diffie−Hellman parameters are encoded into the javax.crypto.spec.DHParameterSpec class, which includes the Diffie−Hellman parameters G, L, and P. The Diffie−Hellman public key interface includes the parameter Y, and the Diffie−Hellman private key interface includes the parameter X.
9.1.2.4 The KeyPair class
There is one additional class, the KeyPair class (java.security.KeyPair), that extends the abstraction of asymmetric keys:
public final class KeyPair
Model a data object that contains a public key and a private key.
The KeyPair class is a very simple data structure class containing two pieces of information: a public key and a private key. When we need to generate our own keys (which we'll do next), we'll need to generate both the public and private key at once. This object will contain both of the necessary keys. If you're not interested in generating your own keys, this class may be ignored.
The KeyPair class contains only two methods:
public PublicKey getPublic( ) public PrivateKey getPrivate( )
Return the desired key from the key pair.
A key pair object is instantiated through a single constructor:
public KeyPair(PublicKey pub, PrivateKey priv)
Create a key pair object, initializing each member of the pair.
In theory, a key pair should not be initialized without both members of the pair being present; there is nothing, however, that prevents us from passing null as one of the keys. Similarly, there are no security provisions within the KeyPair class that prevent the private key from being accessed −− no calls to the security
manager are made when the getPrivate( ) method is invoked. Hence the KeyPair class should be used with caution.