I'm trying to use HKDF after Diffie-Hellman key exchange. However, I got stuck on the HKDF part.

from Crypto.Protocol import HKDF
from Crypto.Hash import SHA512
from Crypto.Random import get_random_bytes

salt = get_random_bytes(16)
key1, key2 = HKDF(master_secret, 32, salt, SHA512, 2)

From my understanding, I only need one key for ChaCha20 or AES-256-GCM. Is it a good idea if I only generate one key by HKDF?

One more thing, how can I generate a good salt for this case?

  • $\begingroup$ Hi kelalaka, Thanks for your comment. I have read through the content from your shared hyperlink. I don't get it. You mean i can skip the expand process and use expand directly? However, if i get OKM from expand process, why do i need to derive salts? $\endgroup$ – Lyf Lan Apr 11 '20 at 11:12
  • $\begingroup$ The salt in HKDF is used to concentrate a possible weak input into short good PRK with the help of a salt. You can skip extract since your key is a Pseudo Random Key. In the Exapand Paradign, use the info to derive even multiple keys. For a nonce generation, see How to generate a nonce for ChaCha20 Poly1305?. The nonce generation is valid for AES-GCM, too. $\endgroup$ – kelalaka Apr 11 '20 at 12:26
  • $\begingroup$ That is exactly what i wanted. Really appreciate! One more thing, how to generate the info part? I have read through the HKDF info part from IETF. It said that it should be independent of the input key material value IKM. Do you have any recommendations? Should info always be different for each communication? $\endgroup$ – Lyf Lan Apr 11 '20 at 13:11
  • 1
    $\begingroup$ "From my understanding, i only need one key" - depends on what you're doing. If you're encrypting in one direction (perhaps encrypting a single message), that's fine. If you're protecting bidirectional traffic (both traffic Alice ends to Bob and what Bob sends to Alice) with the keys generated by a single DH, it'd probably be better to use two keys (one to protect the 'Alice->Bob' traffic and another one to protect the 'Bob->Alice' traffic $\endgroup$ – poncho Apr 11 '20 at 13:26
  • 2
    $\begingroup$ @LyfLan: no, you don't need to do DH twice; HKDF will gladly generate both keys (e.g. if the keys are 256 bits each, ask for 512 bits from HKDF, and use the first half for one key and the other half for the other). As for why, well, it comes to nonce management; both GCM and ChaCha are weak if you use the same nonce for the same key - if you use the same key on both ends, you need to worry whether both sides would use the same nonce to encrypt. If they use different keys, that's not a concern $\endgroup$ – poncho Apr 11 '20 at 15:41

From my understanding, I only need one key for CHACHA20 or AES-256-GCM. Is it a good idea if I only generate one key by HKDF?

In one direction yes, as the MAC and encryption part only requires one key for ChaCha20/Poly1305 and AES-GCM. If you need multiple key parts you can either increase output size and split the result, or you can call HKDF twice using different labels (in the Info component).

Note that you may want to explicitly verify that you generated the same master key on both sides, preferably that should be performed with a separate derived key (and, e.g., HMAC).

One more thing, how can I generate a good salt for this case?

A cryptographic 128 bit salt is fine, as your code seems to be doing at this time.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.