Digestif.PBKDF2 (digestif v0.4.0)

Copy Markdown

PBKDF2-HMAC-SHA-256 password hashing backed by OTP :crypto.

OTP owns salt generation and key derivation. Digestif owns the narrow password-hash layer around it: the modular (passlib-style) encoding, constant-time verification, configuration policy, transparent migration, and the resource preflight described below. The encoding remains compatible with hashes minted by pbkdf2_elixir: unpadded Base64 with . in place of +.

Hashes are always minted explicitly as HMAC-SHA-256 with a 16-byte salt and a 32-byte derived key. :iterations (default 600,000) is the round count for new hashes and dummy work; the validator rejects fewer than 600,000, the OWASP minimum for PBKDF2-HMAC-SHA-256. Do not tune below the floor for tests; use a deliberately cheap custom test hasher instead. Benchmark login latency on production hardware before raising :iterations.

Stored hashes are held to a verification budget: :max_iterations defaults to the configured :iterations and may not fall below it (every hash this configuration mints must stay verifiable), so a hostile, imported, or corrupted value can never make one verification more expensive than a login the host already pays for. Hosts that must keep verifying stronger imported hashes raise the budget explicitly:

{Digestif.PBKDF2,
 iterations: 600_000, max_iterations: 1_000_000}

Trust boundary

Stored hashes are application-controlled database values, not untrusted network input. This adapter bounds the total encoded length before any other inspection and extracts only the algorithm identifier and round count for the budget decision. Values the preflight rejects fail closed after the configured dummy work. Values within that budget must then contain a non-empty salt and one 32-byte digest in the passlib-adapted Base64 alphabet, both canonically encoded; malformed values take the same dummy path.

Hashes minted by Bonafide's pre-extraction, pre-backend adapter used URL-safe Base64 for the salt and digest segments and are not accepted by this passlib-compatible decoder.

Summary

Functions

Returns whether a stored PBKDF2 hash differs from the configured round count. Hashes beyond the verification budget report true as well: they cannot verify under this configuration at all.

Functions

needs_rehash?(encoded_hash, options \\ [])

Returns whether a stored PBKDF2 hash differs from the configured round count. Hashes beyond the verification budget report true as well: they cannot verify under this configuration at all.