Re: Question on Diffie-Hellman and key derivation

Thanks Ryan.

To check I've understood correctly, the answer to my question is actually
"both". For (a), to get a Key object that represents the raw shared secret
and can be used to further derive other keys, I specify the key derivation
algorithm (e.g. HKDF-CTR) as the derivedKeyType and then use deriveKey
again with that Key to get actual encrypt/decrypt/sign/verify algorithm
keys. To get a usable key directly, (b), I just specify the algorithm I
want and the first n bits of the shared secret are used.

...Mark


On Mon, Dec 2, 2013 at 2:28 PM, Ryan Sleevi <sleevi@google.com> wrote:

>
>
>
> On Mon, Dec 2, 2013 at 2:06 PM, Mark Watson <watsonm@netflix.com> wrote:
>
>> All,
>>
>> I have a rather basic question about how Diffie-Hellman is supposed to
>> work in the current draft. I scoured the archives, and whilst there is
>> plenty of discussion of and around this issue, nowhere does there seem to
>> be an answer.
>>
>> The question is, when executing the second DH step, by feeding in the
>> peer public value to deriveKey, what is the output ? Is it:
>> (a) a Key object that represents the raw shared secret bits that are the
>> output of the DH operation, or
>> (b) a Key object that represents a usable key for some other WebCrypto
>> algorithm (say AES-GCM)
>>
>
> Depends on whether you call deriveKey or deriveBits
>
> deriveKey({name: "DH", public: ...}, dhPrivateKey) == error (no derived
> key type specified, cannot be inferred)
> deriveKey({name: "DH", public: ...}, dhPrivateKey, { name: "AES-GCM",
> length: 128}) == first 128-bits of s (the shared secret) as a key
> deriveBits({name: "DH", public: ...}, dhPrivateKey, 128) == first 128 bits
> of s
> deriveBits({name: "DH", public: ...}, dhPrivateKey, 2048) == error if
> len(s) < 2048 bits, otherwise, first 2048 bits
>
> [Mod the outstanding issue about bits/bytes inconsistency]
>
> If you want to derive 2 keys (eg: a decryption and encryption key among
> two parties), you'd need to deriveBits, not deriveKey.
>
> This is *BY DESIGN*, and part of the *very long* discussions about the
> complexities about trying to specify different 'key slicing' schemes.
>
>
>>
>> If (a), what should be specified as the derivedKeyType parameter to
>> deriveKey ? null ?
>>
>> If (b), where are the key derivation algorithm and its parameters
>> specified that derive the key from the raw shared secret bits ?
>>
>
> It's the actual, raw bits of S.
>
> If you want to further feed into a KDF, like HDKF-CTR
>
> deriveKey({name: "DH", public: ...}, dhPrivateKey, { name: "HKDF-CTR",
> hash: { name: "SHA-256" }, label: ..., context: ... }) == a Key object that
> can be used with deriveKey / deriveBits, such that Ki (as defined in
> Section 5.1 of SP 800-108)
>
> You could then
> deriveKey({name: "HKDF-CTR", ...}, hkdfKey, { name: "AES-GCM", length:
> 128}) to get the different keys by varying context.
>
> This of course highlights one bit of ambiguity. SP800-108 defines multiple
> ways of recognized KDFs. In the case of CMAC (not listed ATM), the length
> of Ki can be inferred by the underlying block function, but in the case of
> HKDF-CTR, because HMAC accomodates variable length keys, it's unclear how
> many bits of "s" (the shared secret) should be used as Ki.
>
> These are the kind of bugs that crop up when working through specifying,
> but mod the HKDF key length issue, that's how it "should" work
>
>
>>
>> ...Mark
>>
>>
>>
>
>

Received on Monday, 2 December 2013 22:36:43 UTC