2
$\begingroup$

I have this scenario where I use Encrypt-then-MAC (AES256-CBC and HMAC-SHA256) with keys generated by a CSPRNG (specifically, SecureRandom in Java). I'd like to know which is better:

  • Use the CSPRNG to generate two distinct keys of 32 byte each

or

  • Use the CSPRNG to generate a master key of 32 byte and then use HKDF to derive the encryption and authentication key

I'd like to add that no human interaction is involved: this keys are stored inside a DB and are only used by machines.

Thank you very much!

$\endgroup$

4 Answers 4

3
$\begingroup$

If you are concerned about database size, only the master key needs to be stored when you use HKDF. Ditto when sending it to another computer. Otherwise, two independent random keys are clearly secure and simpler to implement, so you should do that.

$\endgroup$
1
  • $\begingroup$ I'm not concerned about database size, nor to send keys to other computers, so I think I'll use two independent keys. Thanks $\endgroup$
    – Marcello
    Commented Jun 25, 2014 at 12:42
2
$\begingroup$

If you are certain that SecureRandom is a trusted, verified CSPRNG you can use that without HKDF without problems.

$\endgroup$
3
  • $\begingroup$ AFAIK SecureRandom in Java is considered a CSPRNG. Do you think it's not? $\endgroup$
    – Marcello
    Commented Jun 25, 2014 at 11:46
  • $\begingroup$ @Marcello, Java SecureRandom has been shown to be weak on some platforms (Android), and uses an "ad-hoc" construction based on SHA-1 rather than something standardized like HASH-DRBG or at least peer-reviewed like Fortuna. security.stackexchange.com/questions/47871/… $\endgroup$
    – rmalayter
    Commented Nov 25, 2015 at 21:59
  • $\begingroup$ Thanks for your comment. This is a very important thing to know. $\endgroup$
    – Marcello
    Commented Nov 27, 2015 at 1:02
2
$\begingroup$

The other answers are now out of date. You should derive both keys from the same input keying material using a KDF.

If you randomly generate both keys, the construction will not be key- nor message-committing. This can lead to attacks in scenarios where keys can be adversarial. For example, if an attacker can submit a ciphertext encrypted using a password to a server that knows the key (an oracle), they can get a password guessing speedup due to a lack of key commitment.

This has affected the OPAQUE protocol, among others. Amazon also modified their AWS Encryption SDK to include key commitment by default. It's a property that was overlooked when designing AEADs.

As discussed here, it's also important to use a 256-bit+ authentication tag because committing security is about collision resistance.

$\endgroup$
1
  • 1
    $\begingroup$ I agree we should avoid using two different random keys, also because the larger the key, the most inconvenient. Further, in the context of AES256 encryption and HMAC-SHA256 for authentication, and except with regard to the risk of key recovery by side channel leakage, we can in practice safely use the same key for both algorithms, because they use the key so differently. $\endgroup$
    – fgrieu
    Commented Aug 1, 2022 at 10:43
1
$\begingroup$

Either is fine. If you're not concerned about database size or the size of transmitted keys, it doesn't matter which you choose. They are both secure. Choose whichever is more convenient, or easier to implement, or easier for others to interoperate with, or whatever other (non-security) criteria you might have.

$\endgroup$

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.