The KeyAgreement Class

The KeyAgreement class provides the functionality of a key agreement protocol. The keys involved in establishing a shared secret are created by one of the key generators (KeyPairGenerator or KeyGenerator), a KeyFactory, or as a result from an intermediate phase of the key agreement protocol.

Creating a KeyAgreement Object

Each party involved in the key agreement has to create a KeyAgreement object. Like other engine classes in the API, KeyAgreement objects are created using the getInstance factory methods of the KeyAgreement class. A factory method is a static method that returns an instance of a class, in this case, an instance of KeyAgreement, which provides the requested key agreement algorithm.

getInstance takes as its argument the name of a key agreement algorithm. Optionally, a package provider name can be specified:

 public static KeyAgreement getInstance(String algorithm);

 public static KeyAgreement getInstance(String algorithm,
 String provider);

If just an algorithm name is specified, the system will determine if there is an implementation of the requested key agreement available in the environment, and if there is more than one, whether there is a preferred one.

If both an algorithm name and a package provider are specified, the system will determine if there is an implementation of the requested key agreement in the package requested, and throw an exception if there is not.

Initializing a KeyAgreement Object

You initialize a KeyAgreement object with your private information. In the case of Diffie-Hellman, you initialize it with your Diffie-Hellman private key. Additional initialization information may contain a source of randomness and/or a set of algorithm parameters. Note that if the requested key agreement algorithm requires the specification of algorithm parameters, and only a key, but no parameters are provided to initialize the KeyAgreement object, the key must contain the required algorithm parameters. (For example, the Diffie-Hellman algorithm uses a prime modulus p and a base generator g as its parameters.)

To initialize a KeyAgreement object, call one of its init methods:

 public void init(Key key);

 public void init(Key key, SecureRandom random);

 public void init(Key key, AlgorithmParameterSpec params);

 public void init(Key key, AlgorithmParameterSpec params,
 SecureRandom random);

Executing a KeyAgreement Phase

Every key agreement protocol consists of a number of phases that need to be executed by each party involved in the key agreement.

To execute the next phase in the key agreement, call the doPhase method:

 public Key doPhase(Key key, boolean lastPhase);

The key parameter contains the key to be processed by that phase. In most cases, this is the public key of one of the other parties involved in the key agreement, or an intermediate key that was generated by a previous phase. doPhase might return an intermediate key that you might have to send to the other parties of this key agreement, so they can process it in a subsequent phase.

The lastPhase parameter specifies whether or not the phase to be executed is the last one in the key agreeement: A value of FALSE indicates that this is not the last phase of the key agreement (there are more phases to follow), and a value of TRUE indicates that this is the last phase of the key agreement and the key agreement is completed, i.e., generateSecret can be called next.

In the example of Diffie-Hellman between two parties (see Appendix D), you call doPhase once, with lastPhase set to TRUE. In the example of Diffie-Hellman between three parties, you call doPhase twice: the first time with lastPhase set to FALSE, the 2nd time with lastPhase set to TRUE.

Generating the Shared Secret

After each party has executed all the required key agreement phases, it can compute the shared secret by calling one of the generateSecret methods:

 public byte[] generateSecret();

 public int generateSecret(byte[] sharedSecret, int offset);

 public SecretKey generateSecret(String algorithm);