Let's imagine that I've got a number modulo n
given by DH protocol. I want to use it as a key for AES encryption. So I have to cut this number to fit it in AES (128,192 or 256 bits). I can use hash functions to achieve that, but what hash function is suitable for key deriviation? Can I use SHA2?
2 Answers
In principle raw SHA2 is suitable for deriving an AES key from a DH shared secret.
But the "proper" solution is to use a KDF. My preferred choice is HKDF, which can use SHA256 as the underlying hash function. It allows you to derive several named key and keys longer than 256 bits from a single secret.
-
2$\begingroup$ Does this answer assume that the shared secret isn't already a key? I mean, if the DH handshake just exchanges randomized 256-bit data, then is any sort of KDF still required before using that 256-bit data as an AES key? $\endgroup$– NatJul 14, 2017 at 17:53
-
7$\begingroup$ @Nat The output of Diffie-Hellman is a random element of the (sub)group you're doing DH in. It is not uniformly random when treat it as a binary string. $\endgroup$ Jul 14, 2017 at 18:39
Yes.
Actually any cryptographic hash function should be fine and allow you to reduce the problem of breaking your AES encryption to either:
- breaking your DH protocol, this follows from the fact that secure hash functions are meant to be "one-way" function.
- brute-forcing the AES key, since the output of a good hash function is distributed uniformly at random.
But as CodesInChaos mentioned in his answer, the good practice is to use a Key Derivation Function (KDF) to derive a key from a given output.
There are two different kind of KDFs:
- those you use when you have a poor entropy and are afraid of Dictionary Attacks (typically if you store/work with humanly memorable passwords) like Argon2;
- those that you use when you have a good entropy, which is the case if you rely on the DH protocol to establish a common key. In the latter case, the HKDF is completely suited for this, and is actually thought for such need-case.
The advantage of using HKDF is that you already have all the nifty feature you should otherwise implement:
- you have a salt, so you can easily generate multiple keys
- you have the notion of label, so you can generate different keys based on their label
- you have the size as a parameter, so you can easily plug in another encryption function in case AES get broken without changing the key generation algorithm.