hmmnm.com — password hashing done right: a GPU crack attempt deflecting off a wall of memory-hard hash blocks

How to Hash Passwords in 2026: Argon2id, bcrypt and the NIST Baseline

📋 Key Takeaways
  • When an attacker steals your user table, they don't attack your login form — they take the hashes offline and test guesses at full machine speed.
  • The rows tell one story: PBKDF2 is FIPS-approved but memory-free, so it inherits the GPU problem — its only defense is iteration count, which is why OWASP's baseline sits at 600,000 rounds of HMAC-SHA256 and climbing each year.
  • Argon2's RFC 9106 exposes three parameters, and knowing what each buys is the difference between security theater and tuning
  • NIST SP 800-63B (Digital Identity Guidelines) is the compliance baseline, and its password-storage section is shorter than most blog posts: salt shall be at least 32 bits, chosen to minimize collisions and generated from an approved random bit generator; passwords shall be protected by a one-way key derivation function — with memory-hard functions named as the preferred modern option. Everyth…
8 min read · 1,571 words
Educational & Ethical Use Only — This article is provided for educational and ethical cybersecurity research purposes only. The techniques described should only be used on systems you own or have explicit permission to test. Always follow responsible disclosure and the laws applicable to you. Mitigations are included so engineers can harden real systems.
hmmnm.com — password hashing done right: a GPU crack attempt deflecting off a wall of memory-hard hash blocks

TL;DR — Password hashing is an economics problem: you are choosing how expensive it is to test one password guess offline, against attackers with fleets of GPUs where the hash lives. Raw speed — MD5, SHA-1, even bare SHA-256 — is a gift to the attacker. The 2015 Password Hashing Competition’s winner, Argon2 (RFC 9106), makes guessing expensive in memory as well as time, starving the parallelism GPUs live on; OWASP’s floor for Argon2id is 19 MiB of memory and two passes, and NIST’s baseline rules (32-bit minimum salts, approved randomness, a real key-derivation function) remain the compliance line. Here is how the algorithms compare, what the parameters actually do, and the mistakes that keep turning up in breach postmortems.

Passwords were supposed to be dead by now — and passkeys are finally eating the credential landscape — but every passkey deployment still has a legacy password path to migrate, every enterprise has a service somewhere holding a password hash, and every breach disclosure reminds us the same mistakes are eternal. The Kerberos and JWT attack paths we’ve covered recently exploit protocols; password-hash cracking exploits the storage layer underneath — the one component whose strength is entirely your choice of algorithm and parameters.

Why Hashing Is an Economics Problem

When an attacker steals your user table, they don’t attack your login form — they take the hashes offline and test guesses at full machine speed. A modern GPU rig tests tens of billions of MD5 guesses per second; the same rig against a properly configured memory-hard hash drops to thousands. That ratio — the cost you impose per guess — is the entire game, because password entropy at human scale is limited: against a fast hash, a large fraction of real-world passwords fall to commodity dictionaries; against a memory-hard one, the same dictionaries take equipment and time that price most attackers out of everything but the highest-value targets.

The design response is memory-hardness: make each guess require a large block of fast memory as well as serial computation. GPUs and ASICs have enormous raw throughput but comparatively little fast memory per core — so a function that needs 50 MiB per guess runs nearly as slowly on a GPU as on a laptop. Cracking parallelism collapses from “thousands of cores” to “however many memory banks you can afford.”

The Field: Four Algorithms That Matter

Function Origin Design OWASP baseline Use when
Argon2id PHC winner, 2015; RFC 9106 Memory-hard, hybrid side-channel protection m=19456 KiB, t=2, p=1 New systems — the default choice
bcrypt Provos & Mazières, 1999 Blowfish-keyed, adaptive cost, moderate memory use Cost factor 10 Existing stacks; simple and battle-tested
scrypt Percival, 2009; RFC 7914 Memory-hard (ROMix) N=217, r=8, p=1 Legacy choice where Argon2 unavailable
PBKDF2 RFC 2898/8018 Iterated HMAC — CPU-only, no memory 600,000 iters (HMAC-SHA256) FIPS-constrained environments only

The rows tell one story: PBKDF2 is FIPS-approved but memory-free, so it inherits the GPU problem — its only defense is iteration count, which is why OWASP’s baseline sits at 600,000 rounds of HMAC-SHA256 and climbing each year. Argon2id is the inverse: memory is the defense, iterations a secondary cost dial. bcrypt, remarkably, is still respectable a quarter-century later — its 4 KiB working set isn’t memory-hard by modern standards, but its cost factor has aged gracefully and its implementations are rock-solid. (One bcrypt sharp edge to remember: it truncates input at 72 bytes, so pre-hashing long passphrases — carefully, with a wide output — is the standard workaround.)

Argon2id’s Three Knobs

Argon2’s RFC 9106 exposes three parameters, and knowing what each buys is the difference between security theater and tuning:

  • m (memory). The headline defense. Each hash computation fills this much memory — OWASP’s floor is 19 MiB (19,456 KiB), and the practical guidance for new deployments trends well above it, because memory is the resource attackers can’t cheaply scale.
  • t (iterations). Additional passes over memory. Raises time cost without raising memory — useful when you’re capped on RAM per request but can afford CPU.
  • p (parallelism). Independent lanes. Mostly an API-concurrency convenience; keep it low (1–4) and tune m and t instead.

RFC 9106 itself recommends 128-bit salts and at least 128 bits of output, and a new IETF best-practices draft goes further, marking Argon2 as recommended for all new password storage — about as clear as standards bodies get. The tuning target is qualitative, not a number: a hash computation should take a perceptible-but-tolerable fraction of a second on your production hardware (users tolerate a beat at login; attackers feel every millisecond across billions of guesses), re-tuned as hardware improves.

What NIST Actually Requires

NIST SP 800-63B (Digital Identity Guidelines) is the compliance baseline, and its password-storage section is shorter than most blog posts: salt shall be at least 32 bits, chosen to minimize collisions and generated from an approved random bit generator; passwords shall be protected by a one-way key derivation function — with memory-hard functions named as the preferred modern option. Everything else in good practice (larger salts, Argon2, peppers, breach screening) is above the floor, not required by it — which is exactly why treating “NIST-compliant” as the design target produces weak systems. The floor stops at PBKDF2 with a 32-bit salt; you should be floors above it.

800-63B’s other durable contributions to this space are behavioral: length over composition rules, no forced periodic rotation without evidence of compromise, and screening new passwords against known-breach corpora — a control that measurably kills the dictionary problem at enrollment time and costs one API call.

The Perennial Mistakes

  1. Fast hashes. MD5/SHA-1/bare-SHA-256 for passwords — still, in 2026, in shipped products. These are checksums, not password functions; their speed is the vulnerability.
  2. Reused or sequential salts. Same salt for every user means one cracked dictionary cracks the whole table — and precomputed rainbow tables come back into play. Salt per user, from a real RNG.
  3. A pepper implemented as a secret next to the hashes. A pepper (global secret mixed in, stored in config/KMS, not the DB) genuinely helps against DB-only theft — but only if it lives outside the breached perimeter. In the database row, it’s a salt with extra steps.
  4. Parameters set once, never revisited. Hash cost is a hardware-relative quantity; the t=2/m=19MiB you chose in 2020 is weaker on 2026 silicon. Put parameters in the stored hash string (all modern formats do) and plan periodic upgrades.
  5. Legacy-hash upgrade paralysis. The clean pattern is transparent: on successful login, re-hash with modern parameters and store; users never notice, and the legacy population decays. Teams that wait for a “migration project” still have MD5 rows the day the table walks out.

Beyond the Hash

The hash is the last line, not the strategy. In front of it: rate limiting and IP/attempt throttling on the login path (online guessing is a different threat model — cheap guesses there are a bug regardless of hash strength), breach-password screening at enrollment, and MFA or passkeys for anything that matters — because a stolen password database stops being interesting when the password alone no longer authenticates. Defense in depth here is the same principle as anywhere on this site: the detection engineering mindset applied to identity — assume one layer fails, and make the next layer’s cost deliberate.

Key Takeaways

  • Password hashing sets the attacker’s cost per offline guess — favor memory-hard functions (Argon2id) that neutralize GPU parallelism, not fast hashes whose speed only helps attackers.
  • Argon2 (PHC 2015, RFC 9106) with the Argon2id variant is the default for new systems; OWASP’s floor is m=19456 KiB, t=2, p=1, with 128-bit salts per the RFC.
  • bcrypt (1999) remains sound for existing stacks — mind the 72-byte truncation; scrypt and PBKDF2-HMAC-SHA256 (600k iterations) fill legacy and FIPS niches respectively.
  • NIST 800-63B is a floor, not a target: 32-bit minimum salts, approved randomness, a one-way KDF — build well above it.
  • Operational discipline beats algorithm choice: per-user salts, out-of-perimeter peppers, parameters revisited as hardware improves, and transparent re-hash-on-login for legacy rows.

FAQ

Why is Argon2id preferred over bcrypt or PBKDF2?
Memory-hardness: Argon2id forces a large memory allocation per guess, which is exactly what GPU/ASIC crackers lack. bcrypt is CPU/memory-moderate; PBKDF2 is pure CPU and inherits GPU speed.

What parameters should I use for Argon2id?
At minimum OWASP’s baseline (19 MiB memory, 2 iterations, 1 lane), tuned upward until hashing takes a perceptible-but-tolerable fraction of a second on production hardware. Revisit yearly.

What does the salt do, and how big should it be?
It makes each hash unique, defeating precomputation and cross-user cracking. NIST requires ≥32 bits; modern practice uses 128 bits from a cryptographic RNG. Salts are not secrets.

Is a pepper worth adding?
Yes, if stored outside the database — a config-management or KMS secret turns a full database dump into an uncrackable-without-a-second-theft dataset. In-DB peppers do nothing.

Why does PBKDF2 still exist if it’s weaker?
FIPS approval. In regulated environments where only NIST-approved primitives are allowed, PBKDF2 with a high iteration count (600,000+ for HMAC-SHA256) is the compliant option.

How do I migrate away from legacy hashes without a big project?
Re-hash transparently on successful login: verify with the old algorithm, store a fresh Argon2id hash, and force-reset the shrinking remainder. Wrap the old hash in the new scheme if you must keep unverifiable rows.

References

  1. RFC 9106 — Argon2 Memory-Hard Function (PHC winner)
  2. OWASP — Password Storage Cheat Sheet (current baselines)
  3. NIST SP 800-63B — Digital Identity Guidelines (authenticator requirements)
  4. NIST SP 800-63B — official PDF
  5. RFC 7914 — scrypt KDF
  6. RFC 8018 — PBKDF2 (PKCS #5)
  7. Wikipedia — Argon2 (Password Hashing Competition history)
  8. Wikipedia — bcrypt (Provos & Mazières, 1999)
  9. IETF draft — Best practices for password hashing and storage

Current as of September 2026. Educational engineering reference — verify parameter baselines against the current OWASP cheat sheet and NIST revision before production use.

Hmmnm
Published by Hmmnm

Hands-on cybersecurity tutorials, CVE breakdowns, and guided learning paths — written and lab-tested by the Hmmnm team.

🛡️ Hmmnm also delivers this expertise as a service — security testing, assessment & training.

Prabhu Kalyan Samal

Application Security Consultant at TCS. Certifications: CompTIA SecurityX, Burp Suite Certified Practitioner, Azure Security Engineer, Azure AI Engineer, Certified Red Team Operator, eWPTX v3, LPT, CompTIA PenTest+, Professional Cloud Security Engineer, SC-900, SC-200, PSPO I, CEH, Oracle Java SE 8, ISP, Six Sigma Green Belt, DELF, AutoCAD. Writing about ethical hacking, security tutorials, and tech education at Hmmnm.