Everything developers need to know about storing, generating, and validating passwords securely — from bcrypt to entropy calculations.
Password security is one of the most misunderstood areas in web development. Despite years of breaches, developers still make the same mistakes. This guide covers the complete picture — from generating strong passwords to storing them safely.
The 2024 RockYou2024 breach exposed 10 billion plaintext passwords. Most came from applications that stored passwords incorrectly. The patterns are always the same: MD5 hashing, no salting, or — worst of all — plaintext storage.
This should be obvious, but it still happens. If your database is compromised and passwords are plaintext, every user account is immediately compromised. Even encryption is the wrong tool — encryption is reversible, hashing is not.
Cryptographic hash functions like MD5 and SHA-256 are designed to be fast. That's the opposite of what you want for passwords. A modern GPU can compute 10 billion MD5 hashes per second.
bcrypt is intentionally slow. Its work factor (cost factor) lets you tune the computation time:
const bcrypt = require('bcrypt');
// Hashing a password
const saltRounds = 12; // ~300ms on modern hardware — right balance
const hash = await bcrypt.hash(plainPassword, saltRounds);
// Verifying
const isValid = await bcrypt.compare(plainPassword, hash);
Use cost factor 12 for new applications in 2025. Increase it as hardware gets faster — the goal is ~250–500ms per hash.
| Property | SHA-256 | bcrypt |
|---|---|---|
| Designed for passwords | No | Yes |
| Built-in salt | No | Yes |
| Tunable slowness | No | Yes |
| GPU-resistant | No | Partially |
| Recommended for auth | No | Yes |
Strength is measured by entropy — the number of bits of randomness. A password with N bits of entropy requires 2^N guesses on average to crack.
8 chars, lowercase only: ~38 bits → cracked in seconds
12 chars, mixed case+nums: ~70 bits → centuries at bcrypt speed
20 random chars: ~120 bits → effectively uncrackable
The formula: entropy = log2(charset_size^length)
A 12-character password using uppercase, lowercase, numbers, and symbols (94 characters) has log2(94^12) ≈ 78 bits of entropy. That's solid.
1. Rolling your own crypto — always use battle-tested libraries (bcrypt, Argon2, scrypt). Never invent your own hashing scheme.
2. Using MD5 or SHA-1 for passwords — these are broken for password use cases. An attacker with a precomputed rainbow table can crack them instantly.
3. Short minimum password requirements — require at least 12 characters. Better: enforce a minimum entropy threshold rather than character rules.
4. Password complexity rules that backfire — requiring 1 uppercase + 1 symbol leads users to choose Password1!. Longer passphrases are better.
5. Truncating passwords — some systems silently truncate passwords beyond 72 chars (bcrypt's limit). If using bcrypt, SHA-256 prehash the password first to avoid this.
When generating passwords programmatically, use cryptographically secure random number generators:
// Node.js — cryptographically secure
const { randomBytes } = require('crypto');
const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*';
const length = 16;
const password = Array.from(randomBytes(length))
.map(b => charset[b % charset.length])
.join('');
Avoid Math.random() — it is not cryptographically secure.
Argon2 won the Password Hashing Competition in 2015 and is now the recommended choice for new systems:
const argon2 = require('argon2');
const hash = await argon2.hash(password, {
type: argon2.argon2id,
memoryCost: 65536, // 64MB
timeCost: 3,
parallelism: 4,
});
For most web apps today, bcrypt is fine due to its ubiquity and library support. For new high-security systems, Argon2id is the better choice.
Use the free tools above to generate secure passwords, check password strength with entropy scoring, and hash passwords with bcrypt directly in your browser.
Password Generator
Generate cryptographically secure passwords with custom length, character sets, and strength analysis.
Bcrypt Generator
Hash passwords with bcrypt and verify bcrypt hashes. Choose work factor 4–14.
Password Strength Checker
Check password strength with zxcvbn. Get crack-time estimate and specific improvement tips.