How to Create Strong Passwords: A Developer's Security Guide
Weak passwords are the most common entry point for breaches. This guide covers entropy, password policies, secure storage with bcrypt and Argon2, and how to build a compliant password generator.
What Makes a Password Strong: Entropy
Password strength is measured in bits of entropy — the base-2 logarithm of the number of possible passwords given the character set and length. More entropy = exponentially harder to crack.
| Password example | Length | Charset size | Entropy | Time to crack* |
|---|---|---|---|---|
| password | 8 | 26 | 38 bits | < 1 second |
| P@ssw0rd | 8 | 72 | 49 bits | Seconds |
| horse-battery | 13 | 26 | 61 bits | Hours |
| X9#mK2$pQr! | 11 | 94 | 72 bits | Years |
| correct-horse-battery-staple | 28 | 27 | 132 bits | Billions of years |
| Random 20-char alphanumeric | 20 | 62 | 119 bits | Billions of years |
* Assumes 10 billion hashes/second (GPU cluster). bcrypt/Argon2 slow this down by orders of magnitude.
NIST Password Guidelines (2024 Update)
NIST SP 800-63B is the authoritative source for password policy. The 2024 update dropped several outdated requirements and added new ones:
✅ NIST Now Recommends
- Minimum 8 characters (15+ for high-security systems)
- Support passwords up to 64+ characters
- Allow all printable ASCII and Unicode characters
- Check against known breached password lists (Have I Been Pwned API)
- No forced periodic rotation unless compromise is suspected
- No complexity rules (uppercase + number + symbol requirements)
❌ NIST No Longer Recommends
- Mandatory password rotation every 90 days
- Complexity rules (they cause weak but “compliant” passwords like
Password1!) - Security questions
- SMS-only 2FA (allow authenticator apps)
- Truncating passwords at an arbitrary length
How to Store Passwords Securely
The rule is simple: never store a reversible representation of a password. Use a slow, salted hashing algorithm. The salt ensures identical passwords hash differently, defeating rainbow table attacks.
Argon2idimport argon2 from 'argon2';
// Hash on registration
const hash = await argon2.hash(password, {
type: argon2.argon2id,
memoryCost: 65536, // 64 MiB
timeCost: 3, // 3 iterations
parallelism: 4,
});
// Verify on login
const isValid = await argon2.verify(hash, inputPassword);bcryptimport bcrypt from 'bcrypt'; const COST_FACTOR = 12; // ~250ms on modern hardware // Hash on registration const hash = await bcrypt.hash(password, COST_FACTOR); // Verify on login const isValid = await bcrypt.compare(inputPassword, hash);
⚠️ Never use: MD5, SHA-1, SHA-256, or any fast hash for passwords — even with a salt.
Generating Cryptographically Secure Passwords
Use the platform's cryptographic random number generator, never Math.random().
// Browser / Node.js (Web Crypto API)
function generatePassword(length = 20, charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*') {
const bytes = crypto.getRandomValues(new Uint8Array(length));
return Array.from(bytes, (b) => charset[b % charset.length]).join('');
}
// Node.js (crypto module)
import crypto from 'crypto';
const password = crypto.randomBytes(32).toString('base64url').slice(0, 24);Password Security Checklist
- Hash passwords with Argon2id or bcrypt (cost ≥ 10)
- Never log, transmit, or store plain-text passwords
- Use HTTPS everywhere — passwords travel over TLS only
- Check new passwords against Have I Been Pwned (k-anonymity API preserves privacy)
- Implement rate limiting and account lockout on login endpoints
- Add TOTP-based 2FA as an option for all accounts
- Store the cost factor in the hash string so you can upgrade it later without invalidating existing passwords
Generate a strong password instantly
Configure length, character sets, and entropy level — then copy a cryptographically secure password with one click.
Open Password Generator →