Where Password Security Is Actually Won
Before discussing strength, be clear about the attack model — different scenarios demand completely different defences:
| Attack scenario | What the attacker can do | Effective defence |
|---|---|---|
| Credential stuffing | Replay username/password pairs leaked from other sites | Unique password per site + breach screening |
| Online brute force | Guess directly against your login endpoint | Rate limiting + progressive delay + lockout policy |
| Offline cracking | Already holds the database hashes and grinds locally | Slow hashing (Argon2id / bcrypt) + strong salt |
| Phishing | Trick you into typing credentials on a fake site | Passkeys / WebAuthn |
| SIM swap | Take over your phone number | Do not use SMS as a second factor |
Most people believe they are defending against offline cracking, when the actual cause of compromise is credential stuffing — reusing one password across sites. That is also why "a unique random password per site" matters far more than "one very strong but universal password".
To see how strong a given password really is, measure it with the password strength checker, then read on for the reasoning.
Password Entropy: The Formula and Its Limits
The Ideal Formula
E = log₂(R^L), where R is the character set size and L the length:
| Character set | Size | 8 chars | 12 chars | 16 chars |
|---|---|---|---|---|
| Digits only | 10 | 26.6 bit | 39.9 bit | 53.2 bit |
| Lowercase | 26 | 37.6 bit | 56.4 bit | 75.2 bit |
| Upper + lower + digits | 62 | 47.6 bit | 71.4 bit | 95.3 bit |
| All printable | 95 | 52.6 bit | 78.9 bit | 105.2 bit |
Baseline recommendation: randomly generated passwords of 12 or more characters with entropy above 70 bit.
Where the Formula Breaks
It assumes every character is independently and uniformly random. Humans are not a random source, so real entropy falls well below the nominal figure:
| Password | Nominal entropy (95-char set) | Realistic crackability |
|---|---|---|
P@ssw0rd1 |
~52 bit | Dictionary plus common substitutions; hit within tens of thousands of tries |
Qwerty123! |
~52 bit | Keyboard sequence plus digit suffix; extremely fast |
Zhang1985! |
~52 bit | Common surname plus birth year; targeted dictionary cracks it instantly |
Tr0ub4dor&3 |
~65 bit | Still a "word + substitutions + suffix" structure |
Upshot: length matters far more than character variety. Twelve random lowercase letters (about 56 bit, and realistically close to 56) beat eight characters mixing four classes (nominally 52.6 bit, realistically under 30).
zxcvbn: A More Realistic Estimate
Modern strength estimators (zxcvbn and its derivatives) do not count character sets. They recognise patterns first, then estimate guess count:
- Dictionary words (including common names, places, brands, fictional characters)
- Common substitutions (
a→@,o→0,i→1) - Keyboard sequences (
qwerty,1qaz2wsx) - Repeats and runs (
aaaa,12345) - Dates (
1985,20240101) - Structural splitting (
word+123+!scored separately, then combined)
This is the correct explanation for why correct-horse-battery-staple is strong: four random common words give a combination space equal to the wordlist size to the fourth power, while your brain only remembers four words.
Cracking Speed: Why Hash Choice Is Life or Death
The same password hash falls at wildly different rates depending on the algorithm:
| Hash | Attempts per second on one modern GPU | 8-char full-charset brute force |
|---|---|---|
| MD5 | ~10¹¹ | Seconds |
| SHA-256 | ~10¹⁰ | Seconds |
| bcrypt (cost 12) | ~10³ | Years |
| Argon2id (recommended params) | ~10² | Decades |
The key point: MD5 and the SHA family are fast hashes designed for integrity checking and must never be used to store passwords. They optimise for speed, and password storage needs exactly the opposite.
For algorithm selection and parameter tuning, see the password hashing guide: bcrypt vs argon2 vs scrypt. To inspect real hash output, use the bcrypt hash tool, and for output lengths and security status see the hash algorithms cheat sheet.
Three Old Rules NIST Has Reversed
Many systems still run password policies from NIST's 2003 Appendix A. SP 800-63B has explicitly flipped them:
| Old rule | Current stance | Why |
|---|---|---|
| Force a change every 90 days | ❌ Not recommended | Users make small predictable edits; security drops |
| Require upper + lower + digit + symbol | ❌ Not recommended | Pushes users toward patterns like P@ssw0rd1 |
| Security questions | ❌ Should be removed | Answers are usually public information |
| Minimum length ≥ 8 | ✅ Keep (12+ preferred) | Length is the only reliably effective source of complexity |
| Screen against breached passwords | ✅ Strongly recommended | Removes the main ammunition for credential stuffing |
| Allow pasting passwords | ✅ Recommended | Blocking it obstructs password managers |
Breached-Password Screening: How k-Anonymity Works
"Check whether this password appears in a breach corpus" sounds like it requires sending the plaintext. It does not — HIBP's Range API uses k-anonymity:
- The client computes the SHA-1 hash of the password (only to query; never for local storage)
- It sends just the first five characters of that hash
- The server returns every hash suffix matching that prefix (usually a few hundred)
- The client compares locally to see whether the full hash is present
The server never sees your password, nor even the complete hash. The corpus now holds hundreds of millions of entries.
MFA and Passkeys: Choosing Between Options
| Factor | Phishing-resistant | SIM-swap resistant | UX | Verdict |
|---|---|---|---|---|
| Passkeys / WebAuthn | ✅ Strong | ✅ | Best (one biometric tap) | First choice |
| Hardware security key | ✅ Strong | ✅ | Good (must carry it) | High-privilege accounts |
| TOTP app | ❌ Can be relayed live | ✅ | Medium (type 6 digits) | Solid runner-up |
| SMS | ❌ | ❌ | Good | Fallback only |
| Email code | ❌ | ✅ | Medium | As strong as the mailbox |
Why passkeys resist phishing by construction: the private key is bound to a specific domain, and the browser or OS will only sign for a matching domain. A fake site may look identical, but it cannot obtain a signature usable on the real one, because the domains do not match. TOTP cannot do this: if the user types the six digits into a fake site, the attacker relays it to the real one immediately.
Server-Side Defence Checklist
Password security is not only about making users pick strong passwords; server-side gaps are more common:
Storage
- Never store plaintext, and do not use reversible encryption either (a leaked key leaks everything)
- Use Argon2id (preferred) or bcrypt (cost ≥ 12) with a unique random salt per user (≥ 16 bytes)
- Do not use bare MD5 / SHA-1 / SHA-256, and do not build your own "salt + SHA" construction
- Store an algorithm identifier so you can upgrade smoothly (re-hash on next login)
Login Endpoint
- Rate-limit by account, not by IP (IP-based limits make users behind NAT block each other)
- Escalate delay after failures;
lock for 15 minutes after 5 attemptsbeats permanent lockout, which is itself a denial-of-service hole - Do not distinguish "no such user" from "wrong password" in failure messages (it leaks whether an account exists)
- Reset tokens must be single-use, short-lived (≤ 30 minutes), and burned on use — generate high-entropy ones with the token generator
Transport and Logging
- HTTPS everywhere; 301-redirect the login page from HTTP
- Never log passwords, full tokens, or reset links
- Never pass tokens in URL query strings (they land in browser history, Referer headers, and proxy logs)
Monitoring
- Detect anomalous sign-ins (new device, unusual location, burst of failures)
- Integrate breach screening and force a reset on a hit
Personal Checklist
- Use a unique random password for every important site (via a manager, not memory)
- Make the master password a 4–6 random-word passphrase, and enable MFA on it
- Enable passkeys on your email and password manager first — if either falls, everything else can be reset through it
- Choose passkeys over SMS wherever the option exists
- Periodically run your key accounts through breach detection
- Do not reuse passwords just because "this site doesn't matter" — that is exactly what credential stuffing exploits