3
$\begingroup$

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

$\endgroup$
7
  • $\begingroup$ Is there a reason you don't want to use an IV for the purpose of encrypting multiple messages with one key? Or is this about minimizing the risk of compromise by making retroactive decryption difficult? Try Double Ratchet. $\endgroup$
    – forest
    Commented Jan 30, 2019 at 5:53
  • $\begingroup$ I will edit the question since it is not clear but yes I am trying to make it retroactive decryption difficult and I was wondering if hashing the old key is enough to "simulate" the ratchet state since the concept is one way function? $\endgroup$
    – TheSKDown
    Commented Jan 30, 2019 at 6:00
  • $\begingroup$ That is not enough, no. You would need to use the full Double Ratchet protocol. $\endgroup$
    – forest
    Commented Jan 30, 2019 at 6:01
  • $\begingroup$ But for a complete double ratchet I need DH key exchange and a KDF. As stated i already have thought about the DH key exchange since my AES keys are based on it. This leaves me with solving the second part (KDF), so what is the difference between a KDF and a hash function such as SHA-256. They seem to me as the same thing? $\endgroup$
    – TheSKDown
    Commented Jan 30, 2019 at 6:14
  • 1
    $\begingroup$ To find an answer your comment question about the difference between hashes and HKDFs, check Q&As like this one. In short: KDFs must produce results that have certain randomness properties, and be very difficult to reverse while rd hashes only need to satisfy the property "difficult to reverse", without those randomness requirements. Hope that helps… $\endgroup$
    – e-sushi
    Commented Jan 30, 2019 at 7:40

1 Answer 1

3
$\begingroup$

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.

$\endgroup$
2
  • $\begingroup$ You can find a description of KDF1 and KDF2 here :) $\endgroup$
    – Maarten Bodewes
    Commented Feb 13, 2019 at 22:09
  • $\begingroup$ Thanks for the time spent on this answer! Really appreciated! $\endgroup$
    – TheSKDown
    Commented Feb 15, 2019 at 8:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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