awesome-everything RU
↑ Back to the climb

Security

Password hashing: build a migration-safe auth store

Crux Hands-on project — build a password-storage layer on Argon2id with rehash-on-login migration, an external pepper, and timing-safe verify, then prove each property with tests and a benchmark.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at senior altitude — in orbit
◷ 220 min

Reading about password hashing is not the same as shipping an auth store that survives a breach and a hardware decade. Build a small credential layer, seed it with a deliberately weak legacy scheme, then migrate it to Argon2id transparently — proving each property with tests and a benchmark, not assertions.

Goal

Turn the unit’s model into a working, migration-safe password store: a vetted memory-hard KDF with tuned parameters, an external pepper, a constant-time verify, and a rehash-on-login path that upgrades both legacy hashes and aged work factors with zero forced resets.

Project
0 of 7
Objective

Build a password-storage module (Go, Node, or your stack) that hashes with Argon2id at OWASP parameters, peppers outside the DB, verifies in constant time, and transparently migrates legacy and stale hashes at login — then prove every property with automated tests and a tuning benchmark.

Requirements
Acceptance criteria
  • A test suite proving: identical passwords yield different hashes (salt works); a wrong password fails; a correct password verifies; and verify is dispatched correctly across sha256, bcrypt, and Argon2id rows.
  • A migration test: logging in a legacy (sha256 and bcrypt) user upgrades the stored hash to Argon2id in place, and a subsequent login verifies against the new hash — with no password reset.
  • A pepper test showing a hash created with the pepper fails to verify once the pepper is changed or removed, demonstrating the external-secret defense-in-depth.
  • A benchmark output (numbers, not estimates) showing single-hash latency in the target band at the chosen Argon2id parameters, plus a one-paragraph note on how you'd raise the work factor as hardware improves.
Senior stretch
  • Add a breach-response runbook: rotate the pepper, force re-hash on next login, and (since hashes are slow + salted + peppered) decide whether a forced reset is even warranted — with the reasoning written down.
  • Add an Argon2id parameter self-calibration step that measures host throughput at boot and picks memory/time cost to hit the latency target automatically, logging the chosen values.
  • Add a tiny crack-cost demonstration: hash a small wordlist under sha256 vs Argon2id and report the wall-clock difference per N guesses, making the throughput gap concrete.
  • Wire a login-side denial-of-service guard: cap concurrent in-flight Argon2id hashes (each costs 19 MiB) so a flood of login attempts can't exhaust memory, and show the cap holds under a burst.
Recap

This is the loop behind every real auth store: hash with a vetted memory-hard KDF at named OWASP parameters, keep a pepper outside the database for defense-in-depth, verify in constant time, and migrate legacy schemes and aged work factors transparently at login so the table upgrades itself with no forced resets — guarding bcrypt’s 72-byte trap on the way. Proving each property with tests and a benchmark, on a small store, makes the production version muscle memory and gives you the breach-day answer before the breach.

Continue the climb ↑Secrets management: why a key in git is already a breach
shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.