Password Security

Proper password handling protects your users even if your database is stolen. The goal is simple: store passwords so that a breach reveals nothing usable, and make online guessing impractical.

Almost every password disaster comes from one of two mistakes — storing passwords reversibly (plaintext or encryption) or hashing them with a fast algorithm. Both are avoidable with a few lines of code.

TL;DR

Quick Example

Hash on signup, verify on login — bcrypt salts automatically and bakes in a tunable cost:

Core Concepts

Why hashing (not encryption)

Password hashing is a one-way transformation: you store the hash, and on login you hash the input and compare. There's no key to steal and no way to reverse it. Encryption is reversible, so it's the wrong tool — see Encryption.

Three properties make a password hash safe:

Choosing an algorithm

Best Practices

Tune the work factor

Set the cost so a single hash takes ~250–500 ms on your hardware, and raise it over time. Support transparent rehashing when you increase it (rehash on the user's next successful login).

Use modern password policies

Current NIST guidance favors length and breach screening over complexity theater:

Throttle and lock out

Common Patterns

Breached-password check (k-anonymity)

Have I Been Pwned lets you check a password without ever sending it — you send only the first 5 characters of its SHA-1 hash and match the rest locally:

Secure password reset

  1. User requests a reset.
  2. Generate a cryptographically random token.
  3. Store only the hash of the token, with a short expiry.
  4. Email the link containing the token.
  5. Verify, allow the change, then invalidate the token (single use).

Common Mistakes

Hashing with a fast, general-purpose hash

Enforcing arbitrary complexity rules

FAQ

bcrypt or Argon2?

Both are good. Argon2id is the modern first choice (memory-hard, resists GPU/ASIC cracking). bcrypt is perfectly solid, ubiquitous, and well-supported — keep it if it's already in place.

Should I enforce complexity requirements?

No — modern NIST guidance recommends against mandatory composition rules and periodic forced rotation. They push users toward predictable patterns. Favor a longer minimum length plus a breach check.

Do I still need a salt?

Yes, always — but you don't manage it yourself. bcrypt, Argon2, and scrypt generate and store a unique salt as part of the hash automatically.

What's a "pepper"?

A secret value added to passwords before hashing, stored separately from the database (e.g. in a secrets manager). It's an optional extra layer so that a database-only leak still can't be cracked. It complements salting; it doesn't replace it.

Related Topics

References