# crypto.pbkdf2-sha256 PBKDF2 (RFC 8018 section 5.2) with HMAC-SHA256 as its pseudorandom function: it stretches a password and a salt into a key by running HMAC `iterations` times, so that every guess an attacker makes costs the same. It is the algorithm under `auth.password-hash`, which is what an application should normally call; use this directly only to derive keys. Bytes in and out are lists of integers 0 to 255, as everywhere in the registry (see `encoding.hex`). Encode a text password with `encoding.utf8` first. **How many iterations.** OWASP's Password Storage Cheat Sheet recommends 600,000 for PBKDF2-HMAC-SHA256 (2023). Measured on an Apple Silicon laptop, one 32-byte key at a time: | iterations | Python (hashlib) | Rust (release) | TypeScript (Node 24) | |-----------:|-----------------:|---------------:|---------------------:| | 100,000 | 8 ms | 48 ms | 39 ms | | 310,000 | 24 ms | 95 ms | 113 ms | | 600,000 | 47 ms | 178 ms | 222 ms | so 600,000 is affordable in a login request in every language. Record the count with the hash (`auth.password-hash` does) so it can be raised later. **Implementation.** Python uses the standard library's `hashlib.pbkdf2_hmac`, which runs the loop in C. TypeScript and Rust are written out with no `node:crypto` or crates; they precompute the HMAC key's inner and outer pad states once, and hash each 32-byte intermediate as a single pre-padded block, which halves the work of calling HMAC naively and allocates nothing inside the loop. That needs SHA-256's compression function itself, which `crypto.sha256` does not expose, so it is repeated here rather than required. A password longer than 64 bytes is hashed first, as HMAC requires (RFC 2104), and the key may be longer than 32 bytes: each further 32-byte block runs the full iteration count again (RFC 8018's `T_i`), so ask for only what you use. Empty passwords and empty salts are computed, as the RFC allows; refusing a weak salt is `auth.password-hash`'s job (it wants 16 bytes or more). Sources: RFC 8018, PKCS #5: Password-Based Cryptography Specification Version 2.1, section 5.2 (https://www.rfc-editor.org/rfc/rfc8018); the PBKDF2-HMAC-SHA256 test vectors of RFC 7914 section 11 (https://www.rfc-editor.org/rfc/rfc7914#section-11); RFC 6070's inputs (https://www.rfc-editor.org/rfc/rfc6070) with their published SHA-256 results, each confirmed against Python's hashlib; OWASP Password Storage Cheat Sheet (https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html).