howdy/auth/password_hasher

How password credentials are stored. auth.with_passwords uses pbkdf2_sha256, which runs on OTP’s crypto module and needs no native code of its own. A different algorithm, such as Argon2id from a native library, plugs in with auth.with_password_hasher.

Types

The operations Howdy needs from a password hashing algorithm.

  • hash(password) returns a self-describing encoded hash with a fresh random salt.
  • verify(encoded, password) reports whether the password matches, comparing in constant time.
  • needs_rehash(encoded) is True when a stored hash is weaker than this hasher would produce now; Howdy then rehashes it after a successful login.
  • rehash(encoded, password) hashes again without lowering any cost the old hash already exceeds.

Howdy passes NFC-normalized passwords, except when checking a credential stored before normalization was introduced. An Error means the hash could not be produced or read: Howdy fails closed with an internal error and never treats it as a wrong password. Hashing is expensive, so run it where it cannot block a scheduler (a dirty NIF, or OTP’s crypto).

pub type PasswordHasher {
  PasswordHasher(
    hash: fn(String) -> Result(String, Nil),
    verify: fn(String, String) -> Result(Bool, Nil),
    needs_rehash: fn(String) -> Bool,
    rehash: fn(String, String) -> Result(String, Nil),
  )
}

Constructors

  • PasswordHasher(
      hash: fn(String) -> Result(String, Nil),
      verify: fn(String, String) -> Result(Bool, Nil),
      needs_rehash: fn(String) -> Bool,
      rehash: fn(String, String) -> Result(String, Nil),
    )

Values

pub fn pbkdf2_sha256() -> PasswordHasher

PBKDF2-HMAC-SHA256 with 600,000 iterations, a fresh 16 byte salt and a 32 byte hash, OWASP’s recommendation for this algorithm. Hashes are stored in PHC string format:

$pbkdf2-sha256$i=600000,l=32$<salt>$<hash>

with unpadded standard base64. It is not memory-hard: a leaked database costs an attacker less to guess on GPUs than an Argon2id one would, which the password length minimum and common-password check offset.

✨ Search Document