Password Storage

Password Storage

Password storage best practices generator. Algorithm recommendations, salt, pepper, cost factors. Secure password hashing guide.

Configure Your Application

Features

  • Interactive guide to password hashing algorithms: bcrypt, argon2id, scrypt, PBKDF2
  • Configuration recommendations: work factor, memory cost, parallelism
  • Side-by-side comparison of algorithm strengths and weaknesses
  • Code examples for secure password storage in Node.js, Python, Java, Go
  • Common mistakes: MD5, SHA-1, unsalted hashes, unprocessed storage
  • Work factor tuning calculator: target hash time vs. server load

Common Use Cases

  • Choose the right password hashing algorithm for a new application
  • Upgrade from an insecure hashing algorithm (MD5, SHA-1) to a modern one
  • Document password storage security decisions for a compliance audit
  • Train developers on secure password storage practices
  • Tune bcrypt work factor for the right balance of security and performance

Secure Password Storage

Passwords must never be stored in plaintext or with fast hash functions like MD5 or SHA-256. Fast hashes can compute billions of guesses per second on modern GPUs, making offline cracking of a leaked database trivial.

Secure password storage uses adaptive hashing algorithms specifically designed to be slow and memory-intensive: bcrypt, Argon2id, and scrypt. These defeat offline cracking by requiring significant computation per guess, making brute-force attacks economically impractical.

Key properties of secure password hashing: (1) Slow by design — takes ~100–300ms to compute. (2) Salted — a unique random salt per password prevents rainbow table attacks. (3) Adaptive — work factor can be increased as hardware improves. The current OWASP recommendation is Argon2id with appropriate memory and iteration settings.

Examples

Invalid - Insecure: plain MD5
MD5("password")  → Never use for passwords
Valid - Secure: bcrypt
bcrypt.hash(password, 12)  → 12 rounds, ~250ms
Valid - Best: Argon2id
argon2id(password, m=65536, t=3, p=4)

Frequently Asked Questions

Which algorithm should I use: bcrypt, scrypt, or Argon2id?

OWASP recommends Argon2id as the first choice (winner of the Password Hashing Competition). Use bcrypt if Argon2 library support is unavailable or you need maximum ecosystem compatibility. Avoid scrypt for most applications — it's trickier to tune correctly. Never use MD5, SHA-1, or SHA-256 for passwords.

What work factor should I use for bcrypt?

Use the highest factor that keeps hashing time under 300ms on your production server. Start at factor 12 and benchmark: time node -e "require('bcrypt').hash('test', 12, ()=>{})". OWASP recommends a minimum cost factor of 10 (2023). Increase the factor over time as hardware speeds up.

What is a salt and why is it necessary?

A salt is a random string appended to the password before hashing. Each password gets a unique, randomly generated salt. This prevents: (1) identical passwords producing identical hashes, (2) precomputed rainbow table attacks, and (3) an attacker cracking all passwords at once after a breach. Modern libraries (bcrypt, Argon2) handle salting automatically.

How do I migrate from MD5 to bcrypt?

You cannot rehash existing MD5 hashes without the original passwords. The standard migration approach: (1) add a new password_hash column, (2) when a user logs in successfully, rehash their password with bcrypt and store it, (3) after all active users have logged in (typically 90 days), require the remaining users to reset their passwords.

💡 Tips

  • Use the Argon2id algorithm with OWASP's recommended settings: <code>m=65536</code> (64MB memory), <code>t=3</code> iterations, <code>p=4</code> parallelism.
  • Never log passwords — not in debug output, not in request logs, not in error tracking (Sentry, Datadog). Treat them like credit card numbers.
  • Store only the hash and salt — never the plaintext or an intermediate form. The hash is the credential.
  • Implement account lockout or exponential backoff after failed login attempts to prevent online brute-force attacks (regardless of hash strength).