3

I am writing a small chat program to explore some methods and concepts in cryptography and currently I am using a shared AES key tunneled with RSA which upon further reading revealed many flaws both in the mode choice and the concept itself. So after some more videos, articles and posts I decided to implement 2 ECDH pairs which will be used to derive 2 different AES-GCM keys which in terms will be used for message encryption in both directions. On top of that I would like to implement a key derivation per request so that every message is encrypted with its own key derived from the previous. (Synchronicity problems will be handled by the protocol)

Since the initial AES key is not a human password but a high entropy string (which eliminates bruteforcing) is it enough to just hash it with SHA-256 and get the first 128 bits for the seed of the new AES key for efficiency and ease of use? This would prevent decryption of previous messages if the key is compromised which in combination of re-establishing the ECDH pair every so often will limit the threat of a compromised key to minimum in both time directions.

Edit:

Just to make it clear because i added too much context around the question: I am asking if a simple hash function as SHA-256 would play a sufficient role of a KDF in a double ratchet?

This is the proof of concept that I am going to use: https://netnix.org/2015/04/19/aes-encryption-with-hmac-integrity-in-java

Mike Edward Moras
  • 18,161
  • 12
  • 87
  • 240
TheSKDown
  • 33
  • 4

1 Answers1

3

Yes, generally you can use a hash as a "poor man's KDF". For instance, look at the Q/A about KDF1 and KDF2 which are little more than glorified hash functions. Of course, as e-sushi noted, the theoretical requirements of a KDF is a little bit higher than those required of a hash.

Some differences:

  • A KDF doesn't have just one input; besides the Input Keying Material it may also have inputs such as Info containing e.g. a label for the key, a salt and the length of output material to generate;
  • The inputs of the KDF should be canonically encoded or there may be restrictions on the input parameter so that different input combinations will never generate the same output;
  • The output of many KDF's is configurable and may extend the output size of the underlying hash function or block cipher (depending if the KDF supports expansion);
  • The output of the KDF is generally well defined, usually if you want to take 128 bits from a 256 bit hash you take the leftmost bits, but a KDF will have formalized what output should be taken (and yes, I've seen weird / stupid ones);
  • The output of the KDF should be full randomized, which is theoretically not a requirement for hash functions.

Now e.g. SHA-256 or SHA-512 will have output that is indistinguishable from random, so the last point is mostly theoretical in nature. All the other differences can be ignored or implemented in your own hash function. So yes, it is possible to define your own KDF.

However, I'd suggest you use KDF1 so you'd at least be compliant to an existing KDF where all these design choices are already made. KDF1 is very basic and doens't seem to offer canonical encoding, so you may want to make sure that OtherInfo has a static size. In the end, you'd still be left with a single call to a hash. A HMAC based KDF such as HKDF would be considered more secure, of course, as there are few primitives that match a PRF such as HMAC with regards to resilience.

Maarten Bodewes
  • 96,351
  • 14
  • 169
  • 323