PBKDF2 hash generator using WebCrypto
This PBKDF2 hash generator derives a key from a password with PBKDF2 (Password-Based Key Derivation Function 2, defined in RFC 8018). It uses your browser's native WebCrypto implementation, so even 600,000 iterations finish quickly, and it shows how long the derivation took.
What is PBKDF2?
PBKDF2 repeatedly applies an HMAC to the password and salt. Each iteration adds a fixed amount of CPU work, which slows down anyone trying to guess passwords from a stolen hash. It is widely supported (WebCrypto, OpenSSL, Java, .NET, Python's hashlib) and FIPS-approved, which is why regulated environments often require it. Its weakness is that it uses almost no memory, so GPUs can run it in parallel far more cheaply than memory-hard functions.
Example
Password correct horse battery staple, HMAC-SHA256, 600,000 iterations, text salt NaCl, 32-byte key:
Hex: 26ef4d96a6feff19774d092561962aa66640d5fb0bc89a3515b6c25f6e04e9dd
Base64: Ju9Nlqb+/xl3TQklYZYqpmZA1fsLyJo1FbbCX24E6d0=
Salt: 4e61436c (hex)
# Django-style encoded hash
pbkdf2_sha256$600000$NaCl$Ju9Nlqb+/xl3TQklYZYqpmZA1fsLyJo1FbbCX24E6d0=
The last line follows Django's algorithm$iterations$salt$hash layout. Django's default hasher is pbkdf2_sha256 with a text salt and a 32-byte key, so use those settings when you want to compare against a Django database row. With a blank (random), hex or Base64 salt, the salt field of that line holds the Base64 form of the salt bytes; Django would treat that string as a text salt and derive a different key, so such a line does not verify in Django.
Options explained
- PRF – the HMAC hash. HMAC-SHA256 is the common default; HMAC-SHA512 gives more work per iteration; HMAC-SHA1 is only for legacy compatibility (WPA2 and older systems).
- Iterations – default 600,000, the current OWASP guidance for PBKDF2-HMAC-SHA256. OWASP suggests 210,000 for SHA-512. The browser limit is 10,000,000.
- Key length – bytes of output. Asking for more than the hash size (32 bytes for SHA-256) makes PBKDF2 run the whole iteration count again for each extra block.
- Salt is – tells the tool how to read your salt: as UTF-8 text, hex or Base64.
Common errors
- "Salt is not valid hex" – hex salts need an even number of characters from 0-9 and a-f. Switch Salt is to Text if you meant a plain string.
- Slow derivation – very high iteration counts combined with a long key length multiply the work. Reduce the key length to the hash size unless you really need more bytes.
- Salt reuse – every stored password needs its own random salt. A fixed salt is only for reproducing test vectors.
Related tools
For new password storage without FIPS constraints, a memory-hard function such as the Argon2 hash generator is stronger. For a single HMAC without iterations, use the HMAC generator.
Privacy
All derivation happens locally through WebCrypto, and random salts come from crypto.getRandomValues. Nothing is uploaded.