DEV Community

Kokal Limited
Kokal Limited

Posted on • Originally published at strongpassfactory.com

What Makes a Password Actually Good (A Developer's Guide to Entropy)

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)
Enter fullscreen mode Exit fullscreen mode

A 8-character password from the full ASCII printable set (~95 chars) gives you:

8 × log2(95) ≈ 52 bits
Enter fullscreen mode Exit fullscreen mode

A 16-character lowercase-only passphrase (correcthorsebatterystaple-style)?

16 × log2(26) ≈ 75 bits
Enter fullscreen mode Exit fullscreen mode

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 l33t substitutions 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"
Enter fullscreen mode Exit fullscreen mode

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)