On this page:

6 Key Derivation and Password Hashing

A key derivation function can be used to derive a secret key from a master secret such as a passphrase. Typically, KDFs have additional parameters such as salts and work factors.

KDFs are also used to store passwords [HtSSaP, DUB]. A KDF is preferable to a simple digest function (even with a salt) because the work factor can be chosen to make exhaustively searching the space of likely passwords (typically short and composed of alpha-numeric characters) costly. Different KDFs have different parameters, which may control time or space requirements.


(kdf-spec? v)  boolean?

  v : any/c
Returns #t if v is a KDF specifier, #f otherwise.

A KDF specifier is one of the following:


(kdf-impl? v)  boolean?

  v : any/c
Returns #t if v is an implementation of a key-derivation function, #f otherwise.


(get-kdf k [factories])  kdf-impl?

  k : kdf-spec?
  factories : (or/c crypto-factory? (listof crypto-factory?))
   = (crypto-factories)
Returns an implementation of KDF k from the given factories. If no factory in factories implements k, returns #f.


(kdf k pass salt [params])  bytes?

  k : (or/c kdf-spec? kdf-impl?)
  pass : bytes?
  salt : bytes?
  params : (listof (list/c symbol? any/c)) = '()
Runs the KDF specified by k on the password or passphrase pass and the given salt and produces a derived key (or password hash). Additional parameters such as iteration count are passed via params.

The following parameters are recognized for (list 'pbkdf2 'hmac digest):

In 2000 PKCS#5 [PKCS5] recommended a minimum of 1000 iterations; the iteration count should be exponentially larger today.

The following parameters are recognized for 'scrypt:

In 2009 the original scrypt paper [scrypt] used parameters such as 214 to 220 for N, 1 for p, and 8 for r.

The following parameters are recognized for 'argon2d, 'argon2i, and 'argon2id:

> (kdf '(pbkdf2 hmac sha256)
       #"I am the walrus"
       '((iterations 100000) (key-size 32)))



(pbkdf2-hmac di    
  #:iterations iterations    
  [#:key-size key-size])  bytes?
  di : digest-spec?
  pass : bytes?
  salt : bytes?
  iterations : exact-positive-integer?
  key-size : exact-positive-integer? = (digest-size di)
Finds an implementation of PBKDF2-HMAC-di using (crypto-factories) and uses it to derive a key of key-size bytes from pass and salt. The iterations argument controls the amount of work done.

> (pbkdf2-hmac 'sha256 #"I am the walrus" #"abcd" #:iterations 100000)



(scrypt pass    
  #:N N    
  [#:p p    
  #:r r    
  #:key-size key-size])  bytes?
  pass : bytes?
  salt : bytes?
  N : exact-positive-integer?
  p : exact-positive-integer? = 1
  r : exact-positive-integer? = 8
  key-size : exact-positive-integer? = 32
Finds an implementation of scrypt [scrypt] using (crypto-factories) and uses it to derive a key of key-size bytes from pass and salt. The N parameter specifies the cost factor (affecting both CPU and memory resources).


[HtSSaP] Coda Hale, “How to Safely Store a Password: Use bcrypt.” http://codahale.com/how-to-safely-store-a-password/
[DUB] Tony Arcieri, “Don’t Use bcrypt.” http://www.unlimitednovelty.com/2012/03/dont-use-bcrypt.html
[PKCS5] B. Kaliski, “PKCS #5: Password-Based Cryptography Specification.” https://tools.ietf.org/html/rfc2898
[bcrypt] Niels Provos and David Mazières, “A Future-Adaptable Password Scheme.” https://www.usenix.org/legacy/events/usenix99/provos.html
[scrypt] Colin Percival, “The scrypt key derivation function.” http://www.tarsnap.com/scrypt.html
[Argon2] Alex Biryukov, Daniel Dinu, and Dmitry Khovratovich, “Argon2: the memory-hard function for password hashing and other applications.” https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf
[PHC] “Password Hashing Competition.” https://password-hashing.net/