Security
What Actually Makes a Password Strong (The Math, Not the Myths)
· 3 min read
Password advice is a folklore genre: mandatory symbols, changes every 90 days, no dictionary words. Much of it dates to a 2003 NIST document whose own author later apologized for it. The modern replacement (NIST SP 800-63B) is built on how attacks actually work — and it says almost the opposite of the folklore.
The load-bearing concept is entropy: how many equally-likely possibilities an attacker must search. Get comfortable with that one number and every password debate resolves itself with arithmetic.
Entropy in one paragraph
A password drawn uniformly at random from a charset of size C with length L has C^L possibilities — log2(C^L) = L × log2(C) bits of entropy. Each character from the full 94-symbol printable set contributes ~6.55 bits; lowercase-only, 4.7 bits. The exponent is the point: length multiplies possibilities per character, while enlarging the charset only grows the per-character base. Sixteen lowercase letters (~75 bits) beat eight full-charset characters (~52 bits) by a factor of eight million.
The catch: the formula applies to random passwords. Human-invented ones ('Password1!', a pet plus a birth year) occupy a tiny, heavily-mapped corner of the space — cracking dictionaries encode exactly the capitalize-first-append-digit habits that complexity rules force. Composition rules make humans predictable, which is why NIST dropped them.
How cracking actually works
Online attacks — guessing at a login form — are throttled by rate limits and lockouts; nearly any random 10+ character password survives them. The scenario that kills passwords is offline: a breached database of hashes, attacked on hardware the defender doesn't control. A single modern GPU tries on the order of 10^10–10^11 MD5/SHA-1 candidates per second; rented rigs scale that by dozens.
Run the numbers at 10^12 guesses/second: a random 8-character full-charset password (6×10^15 possibilities) falls in under two hours on average. Twelve characters (4.7×10^23) takes ~7,500 years. Sixteen (6×10^31): geological time. The site's hashing matters enormously too — bcrypt or Argon2 slows attackers by factors of 10^4–10^6 versus raw SHA — but you don't control the site's hashing. You control your entropy.
What modern guidance actually says
- Length over composition: allow long passwords (64+), require 8+ (15+ for new NIST revisions' preference), drop mandatory symbol/digit/case rules.
- No scheduled rotation: forced 90-day changes produce Password2024! → Password2025! patterns. Rotate on evidence of compromise, immediately and completely.
- Screen against breach corpora: reject passwords appearing in known leak lists (the haveibeenpwned k-anonymity API does this without seeing the password).
- Unique per site, always: credential stuffing — replaying one breach's passwords everywhere — is how most account takeovers happen. Uniqueness converts a breach into a one-site event.
- MFA on anything that matters: a second factor turns 'password leaked' from catastrophe into inconvenience.
The practical setup for a human life
Nobody memorizes forty unique 16-character strings, and nobody should try. Use a password manager as the source of truth: it generates random passwords (16–20 characters, full charset — autofill makes length free) and remembers them. That reduces your memorization burden to a handful of secrets that must live in your head: the manager's master password, your computer login, disk encryption.
For those few, use passphrases: five or six words drawn randomly from a large list (the diceware method) — 'staple-comet-lagoon-fitness-oak' style. At ~12.9 bits per word from a 7,776-word list, six words is ~77 bits: strong against offline attack, yet typeable on a TV keyboard and memorable in a way Kj#9v!2q never is. Random selection is the non-negotiable part; a sentence you thought of is a quote in someone's dictionary.
Judging generators and checkers
Two properties separate trustworthy password tooling from junk. First, randomness source: secrets must come from a cryptographically secure RNG (crypto.getRandomValues in browsers, secrets in Python) — Math.random() outputs are reconstructable from a handful of observations. Second, data flow: generation and strength-checking should happen locally, in your browser, with nothing transmitted — a password that touched someone else's server was never only yours. Verify with the network tab; honest tools invite the check.