A key agreement algorithm provides a secret quantity shared between the sender and the recipient based on certain types of compatible public keys from both parties. An optional OriginatorKeyInfo parameter child of an AgreementMethod element indicates the information associated with the originator used to determine the key. An optional RecipientKeyInfo child indicates that associated with the recipient.
The AgreementMethod element appears as the content of a KeyInfo element because, like other KeyInfo children, it yields a key. This KeyInfo is, in turn, a child of an EncryptedData, EncryptedKey, or Signature element. The Algorithm attribute (and KeySize child, if any) of the EncryptionMethod element under this EncryptedData or EncryptedKey element or the Algorithm attribute of the SignatureMethod under this Signature element is an implicit parameter to the key agreement computation. That sounds and is a bit complex, but look at Figure 18-2. Trace up from AgreementMethod to KeyInfo. Notice that KeyInfo has three possible ancestors: Signature, EncryptedData, and EncryptedKey. Each of these ancestors has a child that is a keyed cryptographic algorithm, either SignatureMethod or EncryptionMethod. The encryption or signature algorithm used determines how many bits of key are extracted from the shared secret. A KeySize element must be provided under EncryptionMethod if the encryption algorithm does not itself specify the key size. In addition, the sender may include a KA-Nonce element under AgreementMethod to ensure that a different shared secret, and thus different keying material, is generated, even for repeated agreements using the same sender and recipient public keys. For example:
<EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="Example:Block/Alg"> <KeySize>80</KeySize> </EncryptionMethod> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <AgreementMethod Algorithm="Example:Agreement/Algorithm"> <KA-Nonce> Zm9v </KA-Nonce> <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha1"> <OriginatorKeyInfo> <ds:KeyValue>...originator...</ds:KeyValue> </OriginatorKeyInfo> <RecipientKeyInfo> <ds:KeyValue>...recipient...</ds:KeyValue> </RecipientKeyInfo> </AgreementMethod> </ds:KeyInfo> <CipherData>...</CipherData> </EncryptedData>
Figure 18-2. Keylnfo descendant algorithms
If the agreed-upon key is used to encrypt a key, rather than encrypting data, then AgreementMethod would appear inside a KeyInfo inside an EncryptedKey element. If it were used for an authentication code, it would appear inside a KeyInfo inside a Signature element.
Implementation of AgreementMethod is optional. Its syntax follows:
<!-- AgreementMethod DTD --> <!ELEMENT AgreementMethod (#PCDATA|KA-Nonce|DigestMethod|OriginatorKeyInfo| RecipientKeyInfo %Method.ANY;)* > <!ATTLIST AgreementMethod Algorithm CDATA #REQUIRED > <!ELEMENT KA-Nonce (#PCDATA) >
In schema syntax, it has the following form:
<!-- AgreementMethod Schema --> <element name="AgreementMethod" type="xenc:AgreementMethodType"/> <complexType name="AgreementMethodType" mixed="true"> <sequence> <element name="KA-Nonce" minOccurs="0" type="base64Binary"/> <element ref="ds:DigestMethodType" minOccurs="0"> <element name="OriginatorKeyInfo" minOccurs="0" type="ds:KeyInfoType"> <element name="RecipientKeyInfo" minOccurs="0" type="ds:KeyInfoType"> <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/> <!-- (0,unbounded) elements from (1,1) external namespace --> </sequence> <attribute name="Algorithm" type="anyURI" use="required"/> </complexType>
18.2.1 Diffie-Hellman Key Agreement
Diffie-Hellman Identifier: http://www.w3.org/2001/04/xmlenc#dh
A Diffie-Hellman (DH) key agreement involves the derivation of shared secret information based on compatible DH keys from the sender and recipient. As described in Chapter 13, a DH public key includes three quantities: a prime (p), a generator (g), and a quantity (Public) such that
The corresponding private key is x.
Two DH public keys are compatible if they have the same prime and generator. If, for the second one,
then the two parties can calculate the shared secret
even though each knows only its own private key and the other party's public key. Leading zero octets must be maintained in ZZ, so it will be the same length, in octets, as p. The standards require that p be at least 512 bits and g at least 160 bits. To obtain strong security, numerous other complex considerations apply in the generation of DH keys [RFC 2631].
The DH key agreement algorithm is optional to implement. An example of a DH AgreementMethod element follows:
<AgreementMethod Algorithm="http://www.w3.org/2001/04/xmlenc#dh" xmlns:s="http://www.w3.org/2000/09/xmldsig#" > <KA-Nonce> Zm9v </KA-Nonce> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <OriginatorKeyInfo> <s:X509Data><s:X509Certificate> ... </s:X509Certificate></s:X509Data> </OriginatorKeyInfo> <RecipientKeyInfo> <s:KeyValue>...</s:KeyValue> </RecipientKeyInfo> </AgreementMethod>
The AgreementMethod derives some shared secret octet sequence ZZ. The amount of actual keying material needed is calculated as follows:
where "|" is byte stream concatenation and
DigestAlg is the message digest algorithm specified by the DigestMethod child of AgreementMethod.
EncryptionAlg is the URI of the encryption or signature algorithm, including possible key wrap algorithms, where the derived keying material will be used ("Example:Block/Alg" in the EncryptedData example above), not the URI of the agreement algorithm.
KA-Nonce is the base-64 decoding of the text child of the KA-Nonce child of AgreementMethod, if present. As specified in base-64 decoding, white space is ignored. If the KA-Nonce element is absent, it is null.
Counter is a one-byte counter starting at 1 and being incremented by 1. It is expressed as two hexadecimal digits with uppercase letters.
KeySize is the size in bits of the key to be derived from the shared secret represented as the UTF-8 string for the corresponding decimal integer with only digits in the string and no leading zeros. For some algorithms, the key size is inherent in the URI. For others, such as ARCFOUR, it may be explicitly provided.
For example, the initial KM(1) calculation for the EncryptedData example would be as follows, where the two-character UTF-8 sequence "01" represents the byte counter value of 1, ZZ is the shared secret, and "foo" is the base-64 decoding of "Zm9v":
Assuming that ZZ is 0xDEADBEEF, that would be
whose value is
Each application of DigestAlg with a successive counter value produces some potential keying material. From the concatenated string of one or more KMs, enough leading octets are taken to meet the need for an actual key and the remainder discarded. For example, if DigestAlg is SHA1, which produces 20 octets of hash, then for 128-bit AES the first 16 octets from KM(1) would be taken and the remaining 4 octets would be discarded. For 256-bit AES, all of KM(1) suffixed with the first 12 octets of KM(2) would be taken and the remaining 8 octets of KM(2) would be discarded.