public class ESDHKEKParameterSpec
extends java.lang.Object
implements java.security.spec.AlgorithmParameterSpec
This class represents a parameter specification (OtherInfo structure) for the ephemaral static Diffie Hellman key material creation algorithm as described in 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 DESede 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 DESede, 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.
Please note that the parameters represented by this class are different from
the Diffie Hellman parameters (p,g,l) represeneted by class DHParameterSpec which may be used for
initializing a DH KeyPairGenerator or DHKeyAgreement, but not a ESDHKeyAgreement.
A ESDHKeyAgreement only can be
initialized by a ESDHKEKParameterSpec represented by this class for supplying the
OtherInfo object required for generating a shared secret key encryption key
according to RFC 2631. However, on the other side, you cannot use a ESDHKEKParameterSpec
for initializing a DH KeyPairGenerator or a DHKeyAgreement. You will easily
remember this fact when keeping in mind that a DHParameterSpec represents
common DH parameters (p,g,l) whereas a ESDHKEKParameterSpec represents the
OtherInfo structure described above!
A typical application will instantiate a ESDHAgreement, initialize it with its private DH key and its ESDHKEKParameterSpec, perform DH phases as required and finally call method generateSecret thereby supplying the name of the key to be generated, e.g.:
// 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);
// perhaps some random partyAInfo from the sender:
otherInfo.setPartyAInfo(partyAInfo);
// get a new KeyAgreement object
KeyAgreement key_agreement = KeyAgreement.getInstance("ESDH", "IAIK");
// initialize it with the private key and OtherInfo
key_agreement.init(privateKey, otherInfo, random);
// there is just one phase if only 2 entities agree on a common key
key_agreement.doPhase(otherPublicKey, true);
// now generate the shared secret key
SecretKey secretKey = key_agreement.generateSecret("DESede");
ESDHKEKParameters| Constructor and Description |
|---|
ESDHKEKParameterSpec(ObjectID cekWrapAlgorithm,
byte[] suppPubInfo)
Creates a ESDH Diffie-Hellman parameter specification, based on given CEK wrap
algorithm and suppPubInfo.
|
ESDHKEKParameterSpec(ObjectID cekWrapAlgorithm,
int suppPubInfo)
Creates a ESDH Diffie-Hellman parameter specification, based on given CEK wrap
algorithm and suppPubInfo.
|
| Modifier and Type | Method and Description |
|---|---|
java.lang.Object |
clone()
Returns a clone of this ESDHKEKParameterSpec.
|
ObjectID |
getCekWrapAlgorithm()
Returns the CEK wrap algorithm OID.
|
byte[] |
getCounter()
Returns the counter.
|
int |
getCounterAsInt()
Returns the counter as int value.
|
byte[] |
getPartyAInfo()
Returns the partyAInfo.
|
byte[] |
getSuppPubInfo()
Returns the suppPubInfo.
|
int |
getSuppPubInfoAsInt()
Returns the suppPubInfo as int value.
|
void |
incrementCounter()
Increments the counter by 1.
|
void |
resetCounter()
Resets counter to its initial value 00 00 00 01.
|
void |
setCounter(byte[] counter)
Sets the counter.
|
void |
setCounter(int counter)
Sets the counter.
|
void |
setPartyAInfo(byte[] partyAInfo)
Sets the partyAInfo.
|
java.lang.String |
toString()
Returns a string representation of this Object.
|
public ESDHKEKParameterSpec(ObjectID cekWrapAlgorithm, byte[] suppPubInfo)
cekWrapAlgorithm - the CEK wrapping algorithm with which the KEK will be usedsuppPubInfo - the length of the KEK to be generated as byte arrayjava.lang.IllegalArgumentException - if cekWrapAlgorithm is missing or
suppPubInfo is missing or not 32 bits longpublic ESDHKEKParameterSpec(ObjectID cekWrapAlgorithm, int suppPubInfo)
cekWrapAlgorithm - the CEK wrapping algorithm with which the KEK will be usedsuppPubInfo - the length of the KEK to be generated as intjava.lang.IllegalArgumentException - if cekWrapAlgorithm is missing or
suppPubInfo is missing or invalidpublic void setCounter(byte[] counter)
counter - the counter as byte arrayjava.lang.IllegalArgumentException - if counter is null or not 4 bytes longpublic void setCounter(int counter)
counter - the counter as int valuejava.lang.IllegalArgumentException - if counter is null or invalidpublic void resetCounter()
public void incrementCounter()
public void setPartyAInfo(byte[] partyAInfo)
partyAInfo - octet string of random data provided by the senderjava.lang.IllegalArgumentException - if partyAInfo is not 512 bits long orpublic ObjectID getCekWrapAlgorithm()
public byte[] getCounter()
public int getCounterAsInt()
public byte[] getPartyAInfo()
public byte[] getSuppPubInfo()
public int getSuppPubInfoAsInt()
public java.lang.Object clone()
clone in class java.lang.Objectpublic java.lang.String toString()
toString in class java.lang.Object