Guides

What Is Key Stretching? PBKDF2 & Iteration Counts

Nathan Corbettยทยท8 min read

Here's a claim worth sitting with: the fastest hash function you can find is the worst possible choice for storing a password, and the fix isn't a cleverer algorithm โ€” it's running a hash you already have a few hundred thousand times on purpose. That deliberate repetition has a name, key stretching, and once you see what it buys you, the whole design of modern password storage snaps into focus.

The trade-off at the center of it is simple to state: you are spending your own CPU time to buy an attacker's CPU time at a punishing exchange rate. Let me walk through how that works, step by step.

Step 1: understand why fast is the enemy

When a password database leaks, nobody reverses the hashes โ€” hashes don't reverse. The attacker guesses: run a candidate password through the same hash, compare, repeat. A plain SHA-256 is a disaster here precisely because it's fast โ€” a modern GPU runs billions of SHA-256 hashes per second. Speed, the exact property that makes SHA-256 excellent for a checksum, is a liability the moment the input is a password someone is trying to guess.

So the defensive move is counterintuitive: make the hash slow on purpose. Not slow enough to hurt your login endpoint, but slow enough that an attacker's billions-per-second collapses to thousands-per-second. That single change can turn a crack that finishes over a weekend into one that would take centuries.

Step 2: see stretching as reps, not weight

Think about strength training. One push-up is trivial โ€” no training effect at all. The cost, and the result, comes from repetition: doing the movement over and over until the accumulated work is what matters. And crucially, you can't shortcut it. There's no clever trick that gives you the effect of a thousand push-ups without doing roughly a thousand push-ups' worth of work.

Key stretching applies that logic to hashing. A single hash of your password is one push-up โ€” instant, and instantly crackable. Key stretching does the movement again and again, feeding each round's output into the next, thousands or millions of times, until the total work per password is large. The attacker has to redo every one of those reps for every guess. There's no shortcut around the chain, and that lack of a shortcut is the security.

Step 3: meet PBKDF2, the standard way to do it

The oldest widely-deployed key-stretching function is PBKDF2 โ€” Password-Based Key Derivation Function 2, standardized in RFC 8018. Its recipe is deliberately unglamorous: take an underlying pseudorandom function (in practice an HMAC, usually HMAC-SHA256), and apply it to the password and salt over and over for a set number of iterations, chaining each result into the next. After the last iteration you get a derived value of whatever length you asked for.

That output serves two related jobs, which is why PBKDF2 is called a key derivation function and not just a password hash. As a password hash it produces a value safe to store for login. As a KDF it stretches a password or passphrase into a full-strength encryption key โ€” which is exactly why you find PBKDF2 inside WPA2 Wi-Fi authentication, encrypted disk volumes, and password managers. Same mechanism, two uses: turn something a human can remember into something hard to brute-force.

Step 4: turn the one knob that matters

PBKDF2's security lives almost entirely in one parameter: the iteration count. More iterations means more reps per guess, and the cost scales linearly โ€” double the count and you double both your own time and the attacker's. So the tuning rule is the same one that governs bcrypt's cost factor: don't copy a number, measure a time.

Pick iterations so a single derivation takes roughly 200โ€“300 milliseconds on the hardware that actually runs in production โ€” slow enough to punish an attacker, fast enough that a login page still feels instant and a crowd of logins doesn't melt your server. In 2026 that lands PBKDF2-HMAC-SHA256 in the several-hundred-thousand-iterations range, and it keeps climbing as hardware gets faster. This is the progressive-overload part of the analogy: the count that was painful for attackers five years ago is a warm-up today, so the number is supposed to go up over time. A default of 1,000 iterations โ€” a value you'll still see in old tutorials โ€” is far too fast now and should be treated as broken.

Step 5: know what stretching does NOT buy

Here's the trade-off PBKDF2 makes, and its one real weakness. Stretching adds time cost, but no memory cost โ€” each iteration needs almost no RAM. That leaves a door open: an attacker can build hardware with thousands of tiny cores, each grinding PBKDF2 in parallel, because giving each core its trivial memory is nearly free. GPUs and ASICs eat CPU-only work like this for exactly that reason.

Closing that door is what memory-hard functions do. scrypt and Argon2 force each guess to occupy a large block of RAM at once, which strips parallel hardware of its cheap advantage โ€” and the fuller comparison of the two lives in Argon2 vs bcrypt. So the honest verdict on PBKDF2 is: excellent, standardized, FIPS-approved, and everywhere, but time-hard only. For a greenfield system with no compliance constraints, a memory-hard function resists custom cracking hardware better. Where FIPS compliance or maximum portability rules, PBKDF2 with a high iteration count is a perfectly defensible choice.

Step 6: don't forget the salt (and the password itself)

Key stretching handles brute-force resistance, but it doesn't make hashes unique on its own โ€” that's the salt's job. A unique random salt per password ensures identical passwords hash differently and that no single precomputed rainbow table can attack many accounts at once. Salt for uniqueness, stretch for cost; two defenses, two jobs.

And the part no algorithm can do for you: stretching protects the stored value, not a bad password. A million iterations over "summer2026" is still one dictionary word from cracked. You can feel the cost of deliberately-slow hashing in the Bcrypt Generator โ€” raise the rounds and watch each hash take longer, the same intuition PBKDF2's iteration count gives you โ€” confirm a value matches a stored hash with Bcrypt Compare, and contrast it with the SHA-256 Generator to feel how instant a fast hash is. Then start every account from strength by minting a high-entropy secret in the Password Generator, because as what makes a strong password argues, entropy is the half of the job stretching can't cover.

The takeaway

Key stretching is the deliberate art of doing the same hash far too many times โ€” reps, not a heavier weight โ€” so that each password guess costs real, unshortcut-able work. PBKDF2 is the portable, standardized way to do it: an HMAC run for a tuned number of iterations, with the count set to about 200โ€“300 ms on your own hardware and raised as machines get faster. Its limit is that it's time-hard only, so memory-hard scrypt and Argon2 edge it out against custom hardware. Salt every password, stretch it hard, start from real entropy โ€” and the economics of offline cracking stop working in the attacker's favor.

Try the tools

Frequently Asked Questions

What is key stretching?

Key stretching is the technique of taking a low-entropy secret like a password and running it through a deliberately slow, repeated computation to produce a hash or a cryptographic key. The repetition is the whole point: by forcing the hash to run thousands or millions of times, each guess an attacker makes costs meaningfully more time, so a leaked password database is far harder to crack offline than one protected by a single fast hash.

What is PBKDF2?

PBKDF2 (Password-Based Key Derivation Function 2) is a standardized key-stretching function defined in RFC 8018. It repeatedly applies an HMAC โ€” usually HMAC-SHA256 โ€” to the password and salt for a configurable number of iterations, then outputs a derived key of the length you request. It's FIPS-approved and available in essentially every crypto library, which is why you find it in WPA2 Wi-Fi, disk encryption, and many password-storage systems.

How many PBKDF2 iterations should I use?

Tune to time, not to a fixed number. A common 2026 starting point for PBKDF2-HMAC-SHA256 is several hundred thousand iterations, then measured on your production hardware and raised until a single derivation takes roughly 200โ€“300 ms. Copying an old default like 1,000 iterations leaves you far too fast against modern GPUs โ€” the same mistake as leaving bcrypt at a copied 'rounds = 10'.

Is PBKDF2 better than bcrypt?

They solve the same problem differently, and both are deliberately slow. PBKDF2 is CPU-only and extremely portable (FIPS-approved, in every library); bcrypt uses a small fixed memory footprint that resists GPU attacks slightly better. Neither is memory-hard, so for a brand-new system scrypt or Argon2 give stronger resistance to custom cracking hardware. PBKDF2 remains a fine, standards-compliant choice โ€” especially where FIPS compliance is required.

Does key stretching need a salt?

Yes. Every key-stretching function takes a unique random salt per password so identical passwords produce different hashes and no precomputed table can attack many accounts at once. The salt handles uniqueness; the iteration count handles brute-force resistance. They're two separate defenses doing two separate jobs โ€” you need both.

NC

Nathan Corbett writes for CodeUtilityKit, where the team builds free, privacy-first developer tools that run entirely in your browser. Every guide is written and reviewed by developers who use these tools daily.