I am a bit confused about key derivation functions. I am trying to use the argon2 KDF from the passlib python module to do the following:

  1. The user provides a password which I provide to the hash function combined with a salt (which is autogenerated by the function)
  2. I use the resulting hash as a master key to encrypt some other key(s) along with some data about some system, for example a set of files. The salt is also stored along this data (but not encrypted).

My confusion comes from the fact that the library only provides the hash results in the form of strings which may be used to identify if the user of some website typed in the correct password, for example the string


as shown in this example.

Can I use a KDF like argon2 for this purpose? Of course I would have to extract the key and the salt along with the settings from this string to make this work.


Can I use a KDF like argon2 for this purpose? Of course I would have to extract the key and the salt along with the settings from this string to make this work.

Yes, but preferably you would not use the part of the function that creates a string.

Basically a password hash and PBKDF (password based key derivation function) are identical functions. The string that is put out is not part of a description of a PBKDF though, it is the output that is generated if it is used as a password hash (and then only for a specific format).

It is a bit annoying if the string is the only possible output, because the last part of the string is the password hash in base 64 (it's the "digest" in the this description). Now strings are pretty hard to delete from memory in most runtime environments, so you cannot easily clean up after decoding the derived key.

Preferably then you'd find or isolate the PBKDF function itself and use the resulting byte array before it is encoded. Or you could of course use another library that provides this functionality.

  • $\begingroup$ Nitpick, unimportant for this question: not all password hashing functions are PBKDFs. bcrypt isn't a KDF, for example, since it doesn't have any way to set the output length, and that length isn't even a common key size. It's easy to use HKDF on that output to get a key, of course, but that's then no longer pure bcrypt. $\endgroup$ – SAI Peregrinus May 19 at 14:50
  • $\begingroup$ @SAIPeregrinus I'm unaware that having a configurable output size is a requirement for KDF's. Besides that you can just take the leftmost bytes if you want a smaller OKM, and many KDF's do have a maximum for the output size (including HKDF). $\endgroup$ – Maarten Bodewes May 19 at 15:29
  • 1
    $\begingroup$ @SAIPeregrinus If you look at NIST SP 108 then you do get the sentence "A key derivation function iterates a pseudorandom function n times and concatenates the outputs until L bits of keying material are generated, where n = ⎡L/h⎤.". So the KDF's in that document do adhere to your definition, and only the IKM is limited by the function (as the IKM may be put into e.g. CMAC, which uses a block cipher). So yeah, if you'd use their definition then you are definitely correct. And HKDF has a limited but pretty large max output size. $\endgroup$ – Maarten Bodewes May 20 at 10:01
  • $\begingroup$ Yep. A less formal way to look at is that a KDF should be able to generate a key for any common (symmetric) key size to be useful. 256-bit keys are pretty common. bcrypt can't generate a 256-bit output. The hash portion of bcrypt's output (what could be used as a key) is only 192 bits. So without non-trivial extra steps, bcrypt can't be used for AES-256 or ChaCha20. So even if it's a KDF under some definition, it's not (alone) a very good one. bcrypt + HKDF-Expand would be a fine KDF, of course. And this is still not directly relevant to the question, just a nitpick. $\endgroup$ – SAI Peregrinus May 23 at 2:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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