Lion Cipher Lab

Migrate legacy password hashes to Argon2id without forcing a reset (wrap now, rehash on login)

Why it matters

Almost nobody gets to design password storage from scratch. You join a team, open the users table, and find 40-character hex strings: unsalted SHA-1, maybe a batch of salted MD5 from an acquisition years ago. The textbook fix is 'switch to Argon2id', but Argon2id needs the PASSWORD, and you only have the old hashes. Forcing 10,000 people to reset is a support disaster and looks like a breach. Waiting for each user to log in leaves every inactive account's weak hash sitting in the database for years. This lab teaches the move professionals use: wrap every legacy hash in Argon2id today, so the…

What you'll learn

Steps in this lab

  1. The problem you inherited, in plain words
  2. Three ways out, and why you pick the third
  3. Set up a workspace and install argon2-cffi
  4. Build the inherited database
  5. Make every stored hash say what it is
  6. Day zero: wrap every legacy hash in one transaction
  7. The old hashes were still in the file until VACUUM
  8. Replay 30 days of logins: rehash-on-login and a parameter raise
  9. Write the migration report and decide about dormant accounts
  10. A defender's benchmark: what each guess costs
  11. Honest negative: password shucking
  12. Pepper: optional, and only if you can keep it secret
  13. Why not wrap with bcrypt?
  14. Tuning parameters for production
  15. What you did, and the rollout checklist to keep

Open the full interactive lab →