正在加载,请稍候…

How to Generate and Evaluate Strong Passwords

Learn what makes a password strong, how password crackers work, rules for different use cases, and how to generate secure passwords in code.

What Makes a Password Strong?

Password strength comes down to one metric: entropy — the number of bits of randomness an attacker must overcome. More entropy means more combinations to try, which means more time to crack.

The formula:

Entropy (bits) = log₂(Alphabet size ^ Password length)
            = Password length × log₂(Alphabet size)
Character Set Size 12-char entropy 16-char entropy
Digits only 10 39.9 bits 53.1 bits
Lowercase only 26 56.4 bits 75.2 bits
Lower + upper 52 68.4 bits 91.2 bits
Lower + upper + digits 62 71.5 bits 95.3 bits
Lower + upper + digits + symbols 94 78.6 bits 104.8 bits

Modern password crackers on consumer hardware: ~100 billion attempts/second for simple hashes. At that rate:

  • 56-bit entropy: cracked in ~7 months
  • 72-bit entropy: cracked in ~72,000 years
  • 128-bit entropy: heat death of the universe

Practical recommendation: 128+ bits of entropy for passwords stored with strong algorithms; for anything using MD5/SHA1 (which attackers exploit against leaked databases), aim for 80+ bits.

How Attackers Crack Passwords

Understanding attacks helps you defend against them.

Dictionary Attacks

Attackers try common words, names, common substitutions (a→@, e→3, s→5), and append common suffixes (123, 2024!, !):

password → P@ssw0rd → P@ssw0rd123 → P@ssw0rd2024!

RockYou, Have I Been Pwned, and similar wordlists contain billions of common passwords and their variations.

Mask Attacks (Pattern-Based)

If an attacker knows the password policy (must have uppercase, digit, symbol), they narrow the search:

Mask: ?u?l?l?l?l?l?d?s → 1 uppercase + 5 lowercase + 1 digit + 1 symbol

This is why "Password1!" is weak — it matches the most common policy-compliant pattern.

Rainbow Tables

Precomputed hash tables for common passwords. Defeated by password salting (which all good password hashing algorithms do automatically).

What Doesn't Work (Common Misconceptions)

Substitutions (l33tspeak): Attackers include common substitutions in their dictionaries. P@ssw0rd is in every wordlist.

Adding numbers/symbols at the end: Attackers know users do this. correct1! is not much stronger than correct1.

Patterns on keyboard: qwerty, asdfgh, 123qwe are all in every wordlist.

Personal information: Birthdates, pet names, addresses — these are the first things targeted in targeted attacks.

What Actually Works

Random Characters

A truly random 16-character password from the full character set has ~105 bits of entropy and is essentially uncrackable:

Kp7!mNqX3#rL9sYv

The problem: impossible to memorize.

Diceware Passphrases

A string of random common words is both high-entropy and memorable:

correct horse battery staple

5 words from a 7776-word wordlist: log₂(7776^5) = 64.6 bits. Not crackable by brute force.

6 words: 77.5 bits. 8 words: 103.4 bits.

Words beat random characters for memorability at equivalent entropy.

Password Managers

The practical solution: generate a unique, truly random 20+ character password for every service, store them all in a password manager. You only memorize one strong master password.

Generating Passwords in Code

// Browser / Node.js — cryptographically secure
function generatePassword(length = 20, options = {}) {
  const {
    uppercase = true,
    lowercase = true,
    digits = true,
    symbols = true,
  } = options;

  let charset = '';
  if (lowercase) charset += 'abcdefghijklmnopqrstuvwxyz';
  if (uppercase) charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  if (digits) charset += '0123456789';
  if (symbols) charset += '!@#$%^&*()-_=+[]{}|;:,.<>?';

  if (!charset) throw new Error('At least one character type required');

  const array = new Uint32Array(length);
  crypto.getRandomValues(array);

  return Array.from(array)
    .map(n => charset[n % charset.length])
    .join('');
}

// Usage
const password = generatePassword(24, { symbols: true });
// => "Kp7!mNqX3#rL9sYv2@Hf8qR"
import secrets
import string

def generate_password(length=20, use_symbols=True):
    chars = string.ascii_letters + string.digits
    if use_symbols:
        chars += '!@#$%^&*()-_=+[]{}|;:,.<>?'

    # secrets.choice uses os.urandom — cryptographically secure
    return ''.join(secrets.choice(chars) for _ in range(length))

# Diceware-style passphrase
import random

WORDLIST = ['apple', 'bridge', 'cloud', ...]  # load your wordlist

def generate_passphrase(num_words=6):
    return ' '.join(secrets.choice(WORDLIST) for _ in range(num_words))

Password Rules for Different Use Cases

Use Case Minimum Recommended Notes
Web account (bcrypt) 12 chars 20+ chars bcrypt handles work factor
Admin / privileged account 16 chars 30+ chars Use passphrase or password manager
Wi-Fi password 12 chars 20 chars WPA2 has no rate limiting
PIN (4 digits) Use 6 digits Only for low-stakes, locked device
Encryption key passphrase 20 chars Diceware 8 words Protects encrypted volume

Evaluating Password Strength

A simple entropy-based meter:

function estimateEntropy(password) {
  let charset = 0;
  if (/[a-z]/.test(password)) charset += 26;
  if (/[A-Z]/.test(password)) charset += 26;
  if (/[0-9]/.test(password)) charset += 10;
  if (/[^a-zA-Z0-9]/.test(password)) charset += 32;

  const entropy = password.length * Math.log2(charset || 1);

  if (entropy < 40) return { score: 0, label: 'Very Weak' };
  if (entropy < 56) return { score: 1, label: 'Weak' };
  if (entropy < 72) return { score: 2, label: 'Fair' };
  if (entropy < 88) return { score: 3, label: 'Strong' };
  return { score: 4, label: 'Very Strong' };
}

For a more sophisticated analysis (pattern detection, dictionary checking), use the zxcvbn library, which models realistic attack patterns.

→ Test and analyze your password strength with the Password Strength Analyser.