← All modules
Foundations·14 min

Password hashing & key derivation: PBKDF2, bcrypt, scrypt, Argon2

A cryptographic hash is too fast for passwords. KDFs deliberately slow things down — and not all of them do it the same way.

Developer / EngineerSecurity ArchitectGRC / Risk & ComplianceResearcher / Academic

Why SHA-256 alone is the wrong tool for passwords

A general-purpose hash function like SHA-256 is designed to be fast — that's a feature for verifying file integrity and a serious liability for storing passwords. Modern GPUs and ASICs can compute billions of SHA-256 hashes per second, making brute-force and dictionary attacks against a stolen password database dramatically cheap unless the hashing itself is deliberately expensive.

Salting — appending a unique random value to each password before hashing — is a separate, complementary defense: it defeats precomputed rainbow-table attacks by ensuring identical passwords don't produce identical hashes, but it does nothing to slow down an attacker targeting one specific hash.

PBKDF2, bcrypt, and scrypt

PBKDF2 slows things down by applying a hash function repeatedly, thousands or millions of times, controlled by a tunable iteration count — simple and standard, but cheaply parallelizable on GPUs. bcrypt, based on the Blowfish cipher, adds an adjustable "cost factor" and has been a de facto standard since 1999. scrypt goes further, deliberately requiring large amounts of memory as well as computation (memory-hard), which is significantly more expensive to parallelize on specialized hardware.

DK=PBKDF2(password,salt,c,dkLen)\mathrm{DK} = \mathrm{PBKDF2}(\mathrm{password}, \mathrm{salt}, c, \mathrm{dkLen})

c is the iteration count — the tunable "cost" knob; dkLen is the derived key's length.

What the iteration count actually costs an attacker

The iteration count isn't an abstract knob — it directly divides an attacker's guessing rate, which makes it possible to reason about a specific deployment in concrete numbers. If a stolen password database used bare, unstretched SHA-256 and an attacker's GPU can compute 10 billion SHA-256 hashes per second, that's also their password-guessing rate: 10,000,000,000 guesses/sec.

Worked example: the same GPU against PBKDF2 with 100,000 iterations. Each guess now costs 100,000 hash operations instead of one, so the attacker's guessing rate drops to 10,000,000,000 ÷ 100,000 = 100,000 guesses per second — a 100,000-fold slowdown, for the defender's cost of one extra hashing step per login.

guesses/sec=hashes/seciteration count\text{guesses/sec} = \frac{\text{hashes/sec}}{\text{iteration count}}

Practice

The same 10-billion-hash/sec GPU attacks a database hashed with PBKDF2 at 500,000 iterations. How many password guesses per second can the attacker make?

Argon2: the current recommendation

Argon2 won the Password Hashing Competition in 2015 and is now the generally recommended choice for new systems. Like scrypt, it's memory-hard, with independently tunable time, memory, and parallelism costs, and comes in variants (Argon2id is typically recommended) balancing resistance to both GPU/ASIC attacks and side-channel attacks.

Password hashing options, in order of increasing GPU/ASIC resistance

PBKDF2

Iteration-based only. Simple, standard, but cheap to parallelize on GPUs.

bcrypt

Blowfish-based with an adjustable cost factor. De facto standard since 1999.

scrypt

Memory-hard as well as iteration-based — expensive to parallelize on specialized hardware.

Argon2id

2015 competition winner. Independently tunable time, memory, and parallelism; current recommendation.

A different job from HKDF

It's worth distinguishing this family from key derivation functions like HKDF, used to derive multiple cryptographic keys from a single shared secret (for example, inside a TLS or Signal Protocol handshake). HKDF is fast by design — it's deriving keys from data that's already high-entropy, not stretching a low-entropy human password, so slowness would add cost without adding security.

Knowledge check

Test what you just learned →

10 quick questions, with an explanation for every answer.

Up next

X.509 certificates & the PKI trust hierarchy →

A certificate is just a signed statement binding a public key to an identity. Here's what's actually inside one, and how revocation works.