PBKDF2 buys time with repetition alone.
It runs a fast hash hundreds of thousands of times and calls that the cost. No memory pressure, no awkward access pattern, just repetition. That makes it the weakest of the four password functions against dedicated hardware and the one you can find absolutely everywhere.
Everything below this line runs locally
600,000 iterations · 0 network requests
Current iteration counts
These come from the OWASP password storage guidance. They move upward over time as hardware gets faster, so treat any number you find in an older tutorial as out of date rather than as advice.
- PBKDF2-HMAC-SHA1
- 1,300,000 iterations
- PBKDF2-HMAC-SHA256
- 600,000 iterations
- PBKDF2-HMAC-SHA512
- 210,000 iterations
In your own code
Browser, WebCrypto
const key = await crypto.subtle.importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, ['deriveBits']);
const bits = await crypto.subtle.deriveBits(
{ name: 'PBKDF2', salt, iterations: 600000, hash: 'SHA-256' },
key,
256
);Node.js
import { pbkdf2, randomBytes } from 'node:crypto';
const salt = randomBytes(16);
pbkdf2(password, salt, 600000, 32, 'sha256', (err, key) => {
// store salt, iterations and key
});Python
import hashlib, os
salt = os.urandom(16)
key = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 600_000)Questions people ask
- How many iterations should I use?
- OWASP currently lists 600,000 for SHA-256, 210,000 for SHA-512 and 1,300,000 for SHA-1. The numbers differ because the underlying functions run at different speeds, and the goal is a comparable amount of work rather than a comparable count.
- Why is PBKDF2 considered the weakest of the four?
- It needs almost no memory, so the work it demands is exactly the kind a graphics card is built to do in parallel. An attacker gets a much larger speedup over your server than they would against bcrypt, scrypt or Argon2.
- Then why use it at all?
- Availability. It is in nearly every standard library, it is what FIPS validated environments permit, and browsers expose it through WebCrypto with no dependency. Sometimes it is the only option you are allowed, and with a high iteration count it is still far better than a plain hash.
- SHA-512 or SHA-256?
- SHA-512 works on 64 bit words, which most GPUs handle less efficiently than the 32 bit words SHA-256 uses. That gives SHA-512 a small edge in practice. Either is a reasonable choice as long as the iteration count is set to match.
- Where does the salt go?
- PBKDF2 has no standard encoded format, so you store the salt, the iteration count and the hash function alongside the derived key. Write them into the row rather than assuming today’s settings will still be in the code in three years.