JustConvertAll-in-One Convert
Dev

Cryptographically Secure Passwords: How to Generate and Store Them

Weak passwords are the leading cause of account compromise. Learn what makes a password strong, how secure random generation works, and how passwords should be stored.

June 15, 2026·7 min read

The weakest link in most authentication systems is not the cryptography — it is the password. Humans are bad at generating random strings and worse at memorizing them. Automated password managers and generators solve the generation problem; proper server-side hashing solves the storage problem. Understanding both is essential for developers building any system that handles credentials.

What Makes a Password Strong?

Password strength is a function of entropy — the number of bits of randomness in the password. A password chosen uniformly at random from a space of N possibilities has log2(N) bits of entropy. The larger the space and the more random the selection, the harder it is to guess.

A 12-character password using uppercase, lowercase, digits, and symbols draws from a space of about 94 characters per position, giving 94^12 ≈ 4.75 × 10^23 possibilities and roughly 79 bits of entropy. A typical attacker running one billion guesses per second would take millions of years to exhaust this space through brute force.

Entropy = log2(charset_size ^ length)

Lowercase only (26), 8 chars:      log2(26^8)  ≈ 37.6 bits  (weak)
Alphanumeric (62), 12 chars:       log2(62^12) ≈ 71.5 bits  (good)
Full ASCII (94), 16 chars:         log2(94^16) ≈ 105 bits   (excellent)
Diceware 6 words (7776 options):   log2(7776^6) ≈ 77.5 bits (good + memorable)

Cryptographically Secure Random Number Generators

Not all randomness is equal. Most programming language random functions (Math.random(), Python's random module) use pseudorandom number generators (PRNGs) seeded from clock time. These are suitable for simulations and games, not security. A CSPRNG (Cryptographically Secure PRNG) draws from the operating system's entropy pool (Linux: /dev/urandom, Windows: CryptGenRandom) and produces output that cannot be predicted even if previous outputs are known.

In browsers, the correct API is crypto.getRandomValues(). In Node.js, use crypto.randomBytes() from the built-in crypto module. Never use Math.random() for password generation, token creation, or any security-sensitive purpose.

// Browser: cryptographically secure password generation
function generatePassword(length = 16, charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*') {
  const values = new Uint32Array(length);
  crypto.getRandomValues(values);
  return Array.from(values, v => charset[v % charset.length]).join('');
}

Storing Passwords Safely

Passwords must never be stored in plaintext or with reversible encryption. The only acceptable storage mechanism is a password hashing function — a one-way function designed specifically for this purpose. SHA-256 and other general-purpose cryptographic hashes are NOT appropriate for password storage because they are too fast: a modern GPU can compute billions of SHA-256 hashes per second, enabling brute-force attacks against a leaked hash database.

Purpose-built password hashing functions (bcrypt, scrypt, Argon2id) are deliberately slow and memory-intensive, raising the cost of brute-force attacks by orders of magnitude. They also incorporate a random salt — a unique value stored alongside each hash — which prevents precomputed rainbow table attacks and ensures that two users with the same password produce different hashes.

  • bcrypt: battle-tested, widely available, limited to 72-byte inputs, cost factor typically 12–14.
  • scrypt: memory-hard; harder to parallelize on GPUs, but less widely supported in managed runtimes.
  • Argon2id: OWASP's recommended default as of 2023; memory-hard, resists both GPU and ASIC attacks; the modern choice for new systems.
  • PBKDF2-SHA-256: NIST-approved; acceptable when Argon2id is not available, but weaker than the above three.

Password Policies That Actually Help

NIST SP 800-63B (2017) revised the conventional wisdom on password policies. The findings: mandatory rotation (changing passwords every 90 days) decreases security because users make predictable changes. Complexity rules (must contain upper, digit, symbol) lead to predictable patterns like P@ssw0rd1. The correct approach: enforce a minimum length of 8 characters (12+ preferred), check passwords against a list of known-breached passwords (the Have I Been Pwned dataset is free and downloadable), and allow all printable characters including spaces.

The most common cause of credential theft is not brute-force — it is phishing, credential stuffing (trying breached passwords from other sites), and database breaches. Long, unique, randomly generated passwords stored in a password manager defeat all three vectors.
Password Generator — Free Online ToolGenerate cryptographically secure random passwords using the browser's Web Crypto API.

Try the tools