We've all built a signup form and slapped a regex on the password field: "at least 8 characters, one uppercase, one number, one symbol." It feels rigorous. It's mostly theater.
The problem is that complexity rules optimize for the wrong thing. P@ssw0rd! satisfies every checkbox above and is one of the first strings any cracking dictionary tries. What actually matters is entropy — the number of guesses an attacker needs on average.
Entropy, briefly
Entropy scales with the size of the character pool and the length of the password:
bits = length × log2(pool_size)
A 8-character password from the full ASCII printable set (~95 chars) gives you:
8 × log2(95) ≈ 52 bits
A 16-character lowercase-only passphrase (correcthorsebatterystaple-style)?
16 × log2(26) ≈ 75 bits
Longer-but-simpler beats shorter-but-gnarly. Every character you add multiplies the search space; every extra symbol class only adds a bit or two. This is why length is the single highest-leverage variable.
What "good" actually means
- High entropy — aim for 70+ bits for anything that matters. That's roughly 12+ random characters or 5+ random words.
-
Truly random — generated by a CSPRNG, not picked by a human. Humans cluster around dates, keyboard walks, and
l33tsubstitutions that crackers model well. - Unique per site — reuse turns one breach into many. This is non-negotiable, which is why a password manager isn't optional.
Generate them right
Don't hand-roll Math.random() — it isn't cryptographically secure. Use your platform's CSPRNG:
// Node.js
const { randomInt } = require('crypto');
const CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*';
const generate = (len = 20) =>
Array.from({ length: len }, () => CHARS[randomInt(CHARS.length)]).join('');
console.log(generate()); // e.g. "kR8$mZ2!qWfN...@vT4"
For a memorable-but-strong passphrase, pull random words from a wordlist (Diceware-style) using the same CSPRNG.
The takeaway
Stop enforcing symbol soup on your users. Set a generous minimum length, encourage a password manager, check submissions against known-breach lists (the HaveIBeenPwned range API is free and k-anonymized), and let entropy do the heavy lifting.
Good passwords aren't clever. They're long, random, and unique — and ideally you never see them, because a generator made them for you.
Originally published on strongpassfactory.com
Top comments (0)