iaik.security.dh
Class ESDHKeyAgreement

java.lang.Object
  |
  +--javax.crypto.KeyAgreementSpi
        |
        +--iaik.security.dh.ESDHKeyAgreement

public class ESDHKeyAgreement
extends KeyAgreementSpi

This class extends iaik.security.dh.DHKeyAgreement to provide the functionality of the ephemeral static Diffie Hellman key agreement algorithm for generating shared secret key encryption keys as specified by RFC 2631.

RFC 2631 gives a special variant of the Diffie Hellman algorithm, based on the ANSI X9.42 draft. From the shared secret value ZZ shared keying material -- typically used as key encryption key (KEK) for encrypting (wrapping) a content encryption key (CEK) -- is created by repeatedly calculating the SHA-1 hash of ZZ and additional other information:

 KM = H ( ZZ || OtherInfo)
 
where OtherInfo is specified as:
 OtherInfo ::= SEQUENCE {
   keyInfo KeySpecificInfo,
   partyAInfo  [0] OCTET STRING OPTIONAL,
   suppPubInfo [2] OCTET STRING }

 KeySpecificInfo ::= SEQUENCE {
   algorithm OBJECT IDENTIFIER,
   counter OCTET STRING SIZE (4..4) }
 
KeySpecificInfo specifies the CEK wrapping algorithm with which this KEK will be used and a counter (32 bit number, represented in network byte order, initial value is 1 for any ZZ) that is incremented by one every time the above key generation function is run for a given KEK. partyAInfo is a random string provided by the sender, especially required in static-static mode (where the sender has a static key pair with the public key placed in a certificate). suppPubInfo id the length of the generated KEK , in bits, represented as a 32 bit number in network byte order. E.g. for 3DES it would be the byte sequence 00 00 00 C0.

For generating a KEK, the KM above (SHA-1 hash of ZZ || OtherInfo) is calcualted as often as necessary to give the required keying material by concatenating the KM blocks resulting from the several steps. In each step the counter is incremented by 1. For 3DES, e.g., which requires 192 bits of keying material, the algorithm must be run twice, once with a counter value of 1 (to generate K1', K2', and the first 32 bits of K3') and once with a counter value of 2 (to generate the last 32 bits of K3). K1',K2' and K3' are then parity adjusted to generate the 3 DES keys K1,K2 and K3. For RC2-128, which requires 128 bits of keying material, the algorithm is run once, with a counter value of 1, and the left-most 128 bits are directly converted to an RC2 key. Similarly, for RC2-40, which requires 40 bits of keying material, the algorithm is run once, with a counter value of 1, and the leftmost 40 bits are used as the key.

Any application wishing to be participated into a Ephemearl Static Diffie Hellman key agreement for generating a shared secret key according to RFC 2631 has to instantiate the javax.crypto.KeyAgreement class (with "ESDH" as name) and initialize it with its ESDHPrivateKey for bringing in the required private information. A ESDH Hellman private key maybe generated using a proper key pair generator, e.g.:

 KeyPairGnerator esdh_key_gen = KeyPairGenerator.getInstance("ESDH");
 esdh_key_gen.initialize(1024);
 KeyPair esdh_key_pair = esdh_key_gen.generateKeyPair();
 ESDHPrivateKey esdh_priv_key = (EsDHPrivateKey)esdh_key_pair.getPrivate();
 
When initializing the ESDHKeyAgreement, together with the private key a ESDHKEKParameterSpec has to be supplied giving the required other information as described above:
 // we want TripleDES key wrap
 AlgorithmID tripleDesWrap = AlgorithmID.cms_3DES_wrap;
 // key length of KEK:
 int keyLength = 192;
 // generate the OtherInfo
 ESDHKEKParameterSpec otherInfo = new ESDHKEKParameterSpec(tripleDesWrap.getAlgorithm(), keyLength);
 // the sender has supplied random patryAInfo:
 otherInfo.setPartyAInfo(partyAInfo);
 // now create an ESDHKeyAgreement object:
 KeyAgreement esdh_key_agreement = KeyAgreement.getInstance("ESDH");
 esdh_key_agreement.init(esdh_priv_key, otherInfo, random);
 
Each phase of a key agreement is performed by a call to the doPhase method, supplied with some other entity´s public key or some intermediate key resulting from the last phase. When calling doPhase it has to be specified, whether to perform already the last phase of the key agreement or not by setting the lastPhase parameter to true or false:
 esdh_key_agreement.doPhase(esdhPubKey_from_other_entity, true);
 
Actually generating the shared secret is done by calling the generateSecret method:

 byte[] shared_secret = esdh_key_agreemant.generateSecret();
 

Please note that calling generateSecret on a ESDHKeyAgreement may either return already the key material generated from the shared secret value ZZ or just the shared secret value (ZZ, see above). This depends on whether you intialize the ESDHKeyAgreement with ESDHKEKParameterSpec parameters or not, respectively.

Please note that the key material retrieved from calling generateSecret may be different from that contained in the SecretKey retrieved when calling generateSecret(algorithm). A 3DES key, e.g., returned by generateSecret(algorithm) already is parity adjusted, whereas the 3DES key material returned by generateSecret is not parity adjusted.

Please note that a ESDHKeyAgreement has to be initialized with a ESDHKEKParameterSpec (representing the OtherInfo) to be distinguished from a ESDHParameterSpec which may be used for initializing a ESDH KeyPairGenerator or ESDHKeyAgreement (see ESDHKEKParameterSpec for more information on this issue).

Version:
File Revision 16
See Also:
DHKeyAgreement, ESDHKEKParameterSpec, ESDHKEKParameters

Constructor Summary
ESDHKeyAgreement()
          Empty default Constructor.
 
Method Summary
protected  Key engineDoPhase(Key key, boolean lastPhase)
          Returns the key resulting from the next phase of this ESDH key agreement.
protected  byte[] engineGenerateSecret()
          Returns the shared secret key material finally generated by this DH key agreement.
protected  int engineGenerateSecret(byte[] sharedSecret, int offset)
          Generates the shared secret key material finishing this ESDH key agreement procedure and writes it into the given byte array, beginning at the given offset position.
protected  SecretKey engineGenerateSecret(String algorithm)
          Returns the shared secret key material finally generated by this ESDH key agreement as SecretKey to be used for the specified secret key algorithm.
protected  void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random)
          Initializes this Ephemral Static Diffie Helman KeyAgreement with the given key, ESDHKEKParameterSpec, and random seed.
protected  void engineInit(Key key, SecureRandom random)
          Initialized this ESDHKeyAgreement with the given key and random seed.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

ESDHKeyAgreement

public ESDHKeyAgreement()
Empty default Constructor. Only for internal use. An application shall call
 KeyAgreement.getInstance("ESDH");
 
for generating an ESDHKeyAgreement object.
Method Detail

engineInit

protected void engineInit(Key key,
                          AlgorithmParameterSpec params,
                          SecureRandom random)
                   throws InvalidKeyException
Initializes this Ephemral Static Diffie Helman KeyAgreement with the given key, ESDHKEKParameterSpec, and random seed.

The given key constitutes the private DH key of some entity being involved in this DH key agreement procedure. Each entity being involved in a DH key agreement process has to create a KeyAgreement object by using a proper getInstance factory method (e.g. KeyAgreement.getInstance("DH");) and subsequently initialize it with the entity´s private DH key for bringing in the private information which will be accessed when required during any phase of the key agreement process. Any key later supplied to any of the doPhase methods will represent public key material of another participated entity or key material resulting from some previously performed phase (if there are more than two entities involved in the key agreement).

The supplied parameters have to be of type ESDHKEKParameterSpec giving the other information required for later creating the shared secret key: // we want TripleDES key wrap AlgorithmID tripleDesWrap = AlgorithmID.cms_3DES_wrap; // key length of KEK: int keyLength = 192; // generate the OtherInfo ESDHKEKParameterSpec otherInfo = new ESDHKEKParameterSpec(tripleDesWrap.getAlgorithm(), keyLength); // the sender has supplied random patryAInfo: otherInfo.setPartyAInfo(partyAInfo); // now create an ESDHKeyAgreement object: KeyAgreement esdh_key_agreement = KeyAgreement.getInstance("ESDH"); esdh_key_agreement.init(dh_priv_key, otherInfo, random);

Overrides:
engineInit in class KeyAgreementSpi
Parameters:
key - the private ESDH key information of the entity involved in the key agreement
params - the algorithm parameter specification (EDHParameterSpec) representing the OtherInfo required for generating the shared secret key material
random - the random seed
Throws:
InvalidKeyException - if the given key cannot be used for this key agreement or the supplied ParameterSpec is not of type ESDHKEKParameterSpec

engineInit

protected void engineInit(Key key,
                          SecureRandom random)
                   throws InvalidKeyException
Initialized this ESDHKeyAgreement with the given key and random seed.

Please note that calling generateSecret on the ESDHKeyAgreement will just return the shared secret value ZZ and not already the key material generated from the shared secret value ZZ according to RFC 2631. If you want to get the key material you will have to initialize this KeyAgreement with a ESDHKEKParameterSpec.

Overrides:
engineInit in class KeyAgreementSpi
Parameters:
key - the private ESDH key information of the entity involved in the key agreement
random - the random seed
Throws:
InvalidKeyException - if the given key cannot be used for this key agreement

engineDoPhase

protected Key engineDoPhase(Key key,
                            boolean lastPhase)
                     throws InvalidKeyException,
                            IllegalStateException
Returns the key resulting from the next phase of this ESDH key agreement.
Overrides:
engineDoPhase in class KeyAgreementSpi
Parameters:
key - the required key for this phase, supplied by some other entity involved in this key agreement
lastPhase - true if this is the last phase of this key agreemant, false if not
Returns:
the key resulting from this phase, or null if no key is returned by this phase
Throws:
InvalidKeyException - if the given key cannot be used for this key agreement algorithm / phase
IllegalStateException - if the given phase cannot be performed in this state of the key agreement procedure

engineGenerateSecret

protected SecretKey engineGenerateSecret(String algorithm)
                                  throws IllegalStateException,
                                         NoSuchAlgorithmException,
                                         InvalidKeyException
Returns the shared secret key material finally generated by this ESDH key agreement as SecretKey to be used for the specified secret key algorithm.

DES or TripleDES keys are returned parity adjusted. If you want the unadjusted key material use one of the other generateSecret methods.

Please note that this method may either return already the key material generated from the shared secret value ZZ according to RFC 2631 or just the shared secret value (ZZ). This depends on whether you have intialized the ESDHKeyAgreement with ESDHKEKParameterSpec parameters or not, respectively.

Overrides:
engineGenerateSecret in class KeyAgreementSpi
Parameters:
algorithm - the name of the secret key algorithm for which the generated secret key shall be used
Returns:
the generated shared secret as SecretKey
Throws:
IllegalStateException - if this key agreement procedure yet is not ready for being finished by generating the shared secret
NoSuchAlgorithmException - if the given secret key algorithm is not supported
InvalidKeyException - if the generated shared secret cannot be returned as SecretKey matching to the given algorithm

engineGenerateSecret

protected int engineGenerateSecret(byte[] sharedSecret,
                                   int offset)
                            throws IllegalStateException,
                                   ShortBufferException
Generates the shared secret key material finishing this ESDH key agreement procedure and writes it into the given byte array, beginning at the given offset position.

Please note that this method may either return already the key material generated from the shared secret value ZZ according to RFC 2631 or just the shared secret value (ZZ). This depends on whether you have intialized the ESDHKeyAgreement with ESDHKEKParameterSpec parameters or not, respectively.

Please note that the key material retrieved from calling generateSecret may be different from that contained in the SecretKey retrieved when calling generateSecret(algorithm). A 3DES key, e.g., returned by generateSecret(algorithm) already is parity adjusted, whereas the 3DES key material returned by generateSecret is not parity adjusted.

Overrides:
engineGenerateSecret in class KeyAgreementSpi
Parameters:
sharedSecret - the byte array to which the generated secret has to be written
offset - the offset indicating the start position within the output byte array to which to write the generated shared secret
Returns:
the number of bytes that are stored in the output byte array
Throws:
IllegalStateException - if this key agreement procedure yet is not ready for being finished by generating the shared secret
ShortBufferException - if the given output buffer is too small for holding the secret

engineGenerateSecret

protected byte[] engineGenerateSecret()
                               throws IllegalStateException
Returns the shared secret key material finally generated by this DH key agreement.

Please note that this method may either return already the key material generated from the shared secret value ZZ according to RFC 2631 or just the shared secret value (ZZ). This depends on whether you have intialized the ESDHKeyAgreement with ESDHKEKParameterSpec parameters or not, respectively.

Please note that the key material retrieved from calling generateSecret may be different from that contained in the SecretKey retrieved when calling generateSecret(algorithm). A 3DES key, e.g., returned by generateSecret(algorithm) already is parity adjusted, whereas the 3DES key material returned by generateSecret is not parity adjusted.

Overrides:
engineGenerateSecret in class KeyAgreementSpi
Returns:
the generated shared secret within a byte array
Throws:
IllegalStateException - if this key agreement procedure yet is not ready for being finished by generating the shared secret

This Javadoc may contain text parts from Internet Standard specifications (RFC 2459, 3280, 3039, 2560, 1521, 821, 822, 2253, 1319, 1321, ,2630, 2631, 2268, 3058, 2984, 2104, 2144, 2040, 2311, 2279, see copyright note) and RSA Data Security Public-Key Cryptography Standards (PKCS#1,3,5,7,8,9,10,12, see copyright note).

IAIK-JCE 3.1 with IAIK-JCE CC Core 3.1, (c) 1997-2004 IAIK