Bcrypt Hash Generator
Generate bcrypt hashes for secure password storage. Bcrypt is specifically designed for password hashing, with built-in salt and configurable work factor to resist brute-force attacks.
Why Bcrypt for Passwords
| Feature | Bcrypt | SHA-256 |
|---|---|---|
| Purpose | Passwords | General hashing |
| Built-in salt | Yes | No |
| Adjustable slowness | Yes | No |
| GPU resistance | Good | Poor |
| Industry standard | Yes | No (for passwords) |
Bcrypt Hash Format
``
$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4beUYqL1qXWvEwZW
│ │ │ │ │
│ │ │ └─ Salt (22 chars) └─ Hash (31 chars)
│ │ └─ Cost factor (2^12 = 4096 rounds)
│ └─ Version (2b)
└─ Algorithm identifier
`
Bcrypt Implementation
`javascript
// Node.js with bcrypt
const bcrypt = require('bcrypt');
// Hash a password
async function hashPassword(password) {
const saltRounds = 12;
return await bcrypt.hash(password, saltRounds);
}
// Verify a password
async function verifyPassword(password, hash) {
return await bcrypt.compare(password, hash);
}
// Usage
const hash = await hashPassword('mySecretPassword');
// "$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4beUYqL1qXWvEwZW"
const isValid = await verifyPassword('mySecretPassword', hash);
// true
`
Cost Factor (Salt Rounds)
| Rounds | Time (~) | Recommendation |
|---|---|---|
| 10 | ~100ms | Development minimum |
| 11 | ~200ms | Light usage |
| 12 | ~400ms | Recommended default |
| 13 | ~800ms | High security |
| 14 | ~1.6s | Very high security |
Bcrypt Best Practices
1. Use cost factor 12+ for production
2. Never store plain passwords - always hash
3. Don't use pepper with bcrypt (controversial)
4. Increase cost factor as hardware improves
5. Use constant-time comparison (bcrypt.compare does this)
Bcrypt Limitations
| Limitation | Detail |
|---|---|
| Max password length | 72 bytes |
| No keyed hashing | Can't use secret key |
| Single-threaded | Can't parallelize |
Consider Argon2 for new projects (memory-hard, more modern).The Avalanche Effect
A one-character change produces a completely different digest — not a similar one. That
property is what makes a hash useful as a fingerprint:
| Input | MD5 | CRC32 |
|---|---|---|
hello | 5d41402abc4b2a76b9719d911017c592 | 3610a686 |
hello. | d94c10e437d18531e122ed0b45badd2a | 0a39d4f1 |
Hello | 8b1a9953c4611296a827abf8c47804d7 | f7d18982 |
hello and Hello differ by one bit of one byte, and share no part of their output.
RIPEMD-160 of hello is 108f07b8382412612c048d07d13f814118445acd, and of Hello is
d44426aca8ae0a69cdbc4021c64fa5ad68ca32fe` — same story.Digest Length and Collision Resistance
| Algorithm | Output | Birthday bound | Status |
|---|---|---|---|
| CRC32 | 32 bits | ~77,000 values | Checksum only |
| MD5 | 128 bits | 2⁶⁴ in theory | Broken — collisions in seconds |
| SHA-1 | 160 bits | 2⁸⁰ in theory | Broken — SHAttered, 2017 |
| RIPEMD-160 | 160 bits | 2⁸⁰ | No practical attack |
| SHA-256 | 256 bits | 2¹²⁸ | Current standard |
| SHA-512 | 512 bits | 2²⁵⁶ | Standard, faster on 64-bit |
Never Hash a Password With These
A general-purpose hash is designed to be fast, which is exactly wrong for passwords: speed helps the attacker. Use a deliberately slow KDF — bcrypt, scrypt or Argon2id — with a per-password salt. A GPU tries billions of SHA-256 guesses a second and a few thousand bcrypt guesses a second, and that gap is the entire defence.