std/pbkdf2
PBKDF2, the iterated password-based key derivation function (RFC 8018 §5.2).
from "std/pbkdf2" import { Pbkdf2 }This is the module for when the input is a password — something a human chose, with maybe 30 bits of entropy behind it. A plain hash of a password is a rounding error to a GPU. PBKDF2 makes each guess cost iterations HMACs, so the defender picks the attacker's price.
Two rules the type system cannot enforce:
- every password gets its own random salt (
std/random), stored alongside the hash — a shared or absent salt lets one rainbow table break every account; - compare stored and recomputed digests with
std/subtle'sconstantTimeEq, never==.
PBKDF2 is the weakest of the accepted password KDFs: it is compute-hard but not memory-hard, so custom hardware gets a large constant-factor advantage that scrypt and Argon2 deny it. It is still FIPS-approved and NIST-recommended (SP 800-63B), and it is what the standard library ships because a correct PBKDF2 beats a subtly wrong Argon2. Use a high iteration count: OWASP's 2023 floor is 600 000 for HMAC-SHA256 and 210 000 for HMAC-SHA512.
Example
from "std/subtle" import { constantTimeEq }
let salt = "per-user-random-salt"
let stored = Pbkdf2.sha256("hunter2", salt, 600000, 32)!
// later, on login:
let candidate = Pbkdf2.sha256("hunter2", salt, 600000, 32)!
if constantTimeEq(stored, candidate) {
print("signed in")
}Checked against the RFC 6070 and RFC 7914 §11 test vectors in tests/fixtures/pbkdf2Vectors.milo.
API reference
Pbkdf2
pub struct Pbkdf2Pbkdf2 namespace — Pbkdf2.sha256(password, salt, iterations, dkLen) and friends, each returning dkLen raw derived bytes.
Pbkdf2.sha1
fn Pbkdf2.sha1(password: &string, salt: &string, iterations: i64, dkLen: i64): Result<string>PBKDF2-HMAC-SHA1. Present for interoperating with existing stores (WPA2, older Django/OpenSSL formats) and because RFC 6070's test vectors are specified on it. Do not choose it for new password storage.
Returns dkLen raw derived bytes. Errs like sha256.
Pbkdf2.sha256
fn Pbkdf2.sha256(password: &string, salt: &string, iterations: i64, dkLen: i64): Result<string>PBKDF2-HMAC-SHA256. The default choice for new password storage.
Returns dkLen raw derived bytes. Errs on a non-positive iteration count or dkLen, and on a dkLen longer than (2^32-1) x hLen.
Pbkdf2.sha512
fn Pbkdf2.sha512(password: &string, salt: &string, iterations: i64, dkLen: i64): Result<string>PBKDF2-HMAC-SHA512.
Returns dkLen raw derived bytes. Errs like sha256.