3

As indicated at

Key generation for AES-GCM-256 file encryption

I'm currently working on a file encryption software. In the above thread it was suggested that, for performance reasons, I use a combination of scrypt and HKDF.

But how should I go about using HKDF to derive a new key for each file? As suggested in the above thread, I intend to produce a single master key via scrypt and from that I want to derive file encryption keys via HKDF.

So far I have come up with two possible ways of doing this:

(1) Run HKDF (extract-then-expand) with the scrypt result as input key material (ikm) and a NEW random salt for each file to be encrypted

(2) Run HKDF (extract-then-expand) with the scrypt result as ikm, a FIXED random salt, and a random 'info' value for each file to be encrypted

Which - if any of these - is the better or correct way of doing what I want? As I understand it, NIST Special Publication 800-56C, explicitly dsicourages re-using the same ikm and just varying the salt. But I don't exactly understand why and their use case (shared secret Z as ikm) is different from mine.

Ilmari Karonen
  • 46,700
  • 5
  • 112
  • 189
FineJoe
  • 71
  • 1
  • 7

1 Answers1

4

The salt is not required to make HKDF secure. Using a static salt doesn't make too much sense - you should be perfectly fine with using an empty salt. Either you can use an empty salt, or a new random salt. This salt could be generated and prefixed per file. If it is large enough (say 128 bytes) then it would make each encryption key unique so you don't have to depend on filename or other meta information (that could be part of Input) to derive the file encryption key.

The salt makes the HKDF function easier to proof, but I haven't heard on any attacks on KDF's without it - including those that directly use a hash function while they should not.

There is little need to perform the extraction of key material from the output of scrypt. Basically you can already create a key from the output of scrypt. So there is no need to derive the pseudo-random key (PRK) for using HKDF-extract. That way you should be fine with just applying HKDF-expand, making the calculations slightly less computationally intensive.


So you would have:

IKM = scrypt(password, salt1)
K = HKDF-expand(IKM, Input, 256)

where Input is any canonically encoded information that defines the file to be encrypted.


You could also go for:

IKM = scrypt(password, salt1)
PRK = HKDF-extract(IKM, salt2)
K = HKDF-expand(PRK, Input, 256)

In this case Input can even be empty if salt is random enough. The salt can be stored (prefixed) with the encrypted file.

Note that salt1 is used for scrypt which according to the org. answer of your previous question should only be used once. Therefore it cannot be used for HKDF.

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