About Bcrypt Hash Generator
Bcrypt is the gold standard for password hashing, designed specifically to be slow and resistant to brute-force attacks. Unlike fast hash functions (MD5, SHA256), bcrypt incorporates a configurable work factor (cost parameter) that makes each hash computation take longer as hardware improves. Bcrypt automatically handles salt generation, making it nearly impossible for attackers to use rainbow tables or pre-computed attacks. It's the recommended password hashing algorithm by OWASP, used by millions of applications including WordPress, Ruby on Rails, and enterprise systems. Our Bcrypt Hash Generator lets you securely hash passwords, verify existing hashes, and understand bcrypt parameters - all processed locally in your browser.
What is Bcrypt?
Bcrypt is a password hashing function designed by Niels Provos and David Mazières in 1999, based on the Blowfish cipher. Unlike general-purpose hash functions (MD5, SHA256) that are designed to be fast, bcrypt is intentionally slow - a critical feature for password security. Key innovations: (1) Adaptive cost factor - you can increase work as computers get faster, future-proofing your hashes. (2) Automatic salt generation and storage - each password gets a unique random salt embedded in the output. (3) Computationally expensive - resistant to GPU/ASIC acceleration due to memory-hard algorithm. (4) Standardized format - bcrypt hashes encode algorithm version, cost, salt, and hash in one string. A bcrypt hash looks like: $2b$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy where $2b$ is version, $10$ is cost (2^10 iterations), next 22 chars are salt (Base64), final 31 chars are the hash. Bcrypt is slower than modern alternatives (Argon2, scrypt) but remains industry standard due to wide support, proven security record, and simplicity.
How to Use This Tool
- Hash Password: Enter a password and click Generate to create bcrypt hash
- Set Cost Factor: Choose 10-12 for web apps, 12-14 for sensitive systems (higher = slower)
- View Hash Components: See decoded salt, cost, and hash value separately
- Verify Password: Compare a password against an existing bcrypt hash
- Test Cost: Measure hash generation time to choose appropriate cost for your server
- Copy Hash: One-click copy for storing in database or config files
- Batch Generation: Generate multiple hashes with different costs for comparison
- Security Note: Real applications should hash passwords server-side, not in browser
- Educational Use: This tool helps understand bcrypt format and parameters
- All Computation Local: Passwords and hashes never leave your browser
Common Bcrypt Use Cases
- User Registration: Hash passwords before storing in database
- Login Verification: Compare entered password with stored bcrypt hash
- Password Reset: Generate new hash when user changes password
- API Keys: Hash sensitive API keys or tokens (though consider alternatives for high-traffic)
- Admin Passwords: Higher cost factors (14+) for administrative accounts
- Legacy Migration: Upgrade from MD5/SHA to bcrypt (rehash on next login)
- Security Audits: Verify existing password hashes are using adequate cost factor
- Testing: Generate test password hashes for development environments
- Compliance: Meet OWASP, PCI-DSS, HIPAA password storage requirements
- Multi-Factor Auth: Hash TOTP secrets or backup codes (though encryption often better)
- Session Tokens: Hash tokens before database storage (prevents token reuse if DB leaked)
- Webhook Secrets: Hash long-lived secrets that don't need high-frequency verification
Why Bcrypt for Passwords (Not MD5 or SHA256)
- Speed is a Bug: MD5/SHA256 are fast (billions of hashes/sec on GPU) - attackers can try passwords quickly
- Bcrypt is Slow: Intentionally takes 100-300ms per hash - brute-force becomes impractical
- GPU Resistance: Bcrypt is memory-hard, expensive to parallelize on GPUs/ASICs
- Salt Built-In: Bcrypt auto-generates random salt, preventing rainbow table attacks
- No Salt Reuse: Every password gets unique salt even if passwords are identical
- Future-Proof: Cost factor adjusts for Moore's Law - increase as hardware improves
- MD5/SHA are Broken: MD5 has collisions, SHA1 deprecated, neither designed for passwords
- Real Attack: LinkedIn (2012) used unsalted SHA1 - 95% of 6.5M passwords cracked in days
- OWASP Recommendation: Bcrypt is OWASP top choice alongside Argon2, scrypt, PBKDF2
- Industry Standard: Rails, Laravel, Spring Security, WordPress all default to bcrypt
- Never Use: Plain text, MD5, SHA256, SHA512 for password storage - always use bcrypt/Argon2
Understanding Bcrypt Cost Factor
- Cost Parameter: Number from 4-31, represents 2^cost iterations (10 = 1,024 iterations)
- Default: Most frameworks use 10-12 (takes ~100-300ms per hash)
- Recommended: 12 for general web apps, 14+ for admin/sensitive accounts
- Performance Impact: Each +1 to cost doubles the time (10=100ms, 11=200ms, 12=400ms)
- Hardware Dependent: Same cost takes different time on different CPUs
- Target Time: Aim for 250-500ms per hash - noticeable to user but not annoying
- Login Impact: Cost 12 means login takes ~300ms for password check (acceptable)
- Brute-Force Math: Cost 12 = 1 password/300ms = 200,000 passwords/day per CPU
- Future Planning: Increase cost every 2-3 years as hardware improves
- Too Low: Cost <10 is vulnerable to modern attacks (GPUs can try millions/sec)
- Too High: Cost >14 may slow down legitimate logins, risk DoS attacks
- Best Practice: Benchmark on your server, choose cost that takes 250-500ms
Bcrypt Hash Format Explained
Bcrypt hashes are self-describing strings containing all necessary information. Format: $2b$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy. Breakdown: (1) $2b$ = Algorithm version (2a, 2b, 2y - use 2b for modern apps). (2) $10$ = Cost factor (2^10 = 1,024 iterations). (3) N9qo8uLOickgx2ZMRZoMye = 22-character Base64-encoded salt (128 bits). (4) IjZAgcfl7p92ldGxad68LJZdL17lhWy = 31-character Base64-encoded hash (184 bits). Total length: Always 60 characters. Database storage: Use CHAR(60) or VARCHAR(72) (allows future versions). The format means you can increase cost factor later and still verify old hashes - just rehash on next successful login. Version differences: $2a$ (original), $2b$ (fixed rare null-byte bug), $2y$ (PHP-specific). Always use $2b$ for new hashes. Never extract salt to reuse elsewhere - bcrypt generates new salt for each password automatically.
Bcrypt vs Argon2 vs Scrypt vs PBKDF2
- Bcrypt: Industry standard, battle-tested (1999), wide support, adequate security. Best for: Most web apps
- Argon2: Modern (2015), won Password Hashing Competition, memory-hard, configurable. Best for: New high-security projects
- Scrypt: Memory-hard (2009), resistant to hardware attacks, higher memory usage. Best for: Cryptocurrency, key derivation
- PBKDF2: Simple (2000), NIST approved, but lacks memory-hardness (GPU-vulnerable). Best for: Compliance requirements only
- Speed: PBKDF2 β bcrypt < scrypt < Argon2 (slower = better for passwords)
- Memory: PBKDF2 (low) < bcrypt (moderate) < scrypt (high) < Argon2 (configurable)
- Support: Bcrypt > PBKDF2 > Argon2 > scrypt (library availability)
- Recommendation: Bcrypt for existing apps (don't migrate unless breached), Argon2 for new projects requiring max security
- Migration: If upgrading from MD5/SHA, go to bcrypt. If starting fresh in 2026, consider Argon2id
- Never Downgrade: Don't move from bcrypt to PBKDF2 or faster algorithms
Implementing Bcrypt Correctly
- Server-Side Only: NEVER hash passwords in JavaScript client-side (defeats purpose, exposes hash)
- Use Libraries: bcrypt.js (Node), bcrypt (Python), BCrypt.Net (C#), Spring Security BCrypt (Java)
- Generate: await bcrypt.hash(password, 12) - cost 12, auto salt
- Verify: await bcrypt.compare(password, hash) - returns true/false, timing-safe
- Store Hash Only: Never store plain password or salt separately - hash contains both
- Database Column: CHAR(60) or VARCHAR(72) for bcrypt hashes
- Error Handling: Catch exceptions (invalid hash format, null values)
- Rehashing: On successful login, check if hash cost is current - rehash if old
- Password Validation: Enforce minimum length (8+ chars), complexity before hashing
- Rate Limiting: Limit login attempts to prevent brute-force even with bcrypt
- HTTPS Only: Transmit passwords only over encrypted connections
- Never Log: Don't log passwords or hashes in application logs
Bcrypt Security Best Practices
- Cost Factor: Use 12 minimum, 14 for sensitive systems, never below 10
- Regular Updates: Increase cost every 2-3 years as hardware improves
- Unique Salts: Bcrypt does this automatically - never reuse salts manually
- Timing-Safe Comparison: bcrypt.compare() is constant-time - prevents timing attacks
- Password Policies: Enforce strong passwords (length, complexity) before hashing
- Account Lockout: Limit failed login attempts (5-10) to prevent brute-force
- Leaked Password Detection: Check against haveibeenpwned.com API during registration
- Pepper (Optional): Add application-wide secret before hashing for extra security
- Migrate Old Hashes: Transparently upgrade MD5/SHA users to bcrypt on next login
- Audit Logs: Log failed login attempts (but not passwords) for security monitoring
- No Client Hashing: JavaScript bcrypt doesn't protect against server compromise
- Database Encryption: Encrypt DB backups containing password hashes
Common Bcrypt Mistakes to Avoid
- Wrong: Hashing in browser JavaScript - attacker can intercept hash and replay it
- Wrong: Storing plain password + hash - defeats entire purpose
- Wrong: Using cost <10 - vulnerable to modern GPU attacks
- Wrong: Extracting and storing salt separately - bcrypt handles this
- Wrong: Using === to compare hashes - must use bcrypt.compare() (timing-safe)
- Wrong: Pre-hashing with MD5/SHA before bcrypt - weakens security, no benefit
- Wrong: Truncating passwords before hashing - limits entropy
- Wrong: Using same cost for all accounts - admins should have higher cost
- Right: Hash on server with cost 12, store 60-char result, verify with bcrypt.compare()
- Right: Rehash on login if old cost factor, use HTTPS, rate-limit attempts
- Right: Trust the library - don't try to optimize or modify bcrypt algorithm
Migrating from MD5/SHA to Bcrypt
If you have existing passwords hashed with MD5 or SHA, you can't convert them to bcrypt (hashing is one-way). Migration strategy: (1) Add new column bcrypt_hash to users table. (2) On next successful login, hash password with bcrypt, store in new column. (3) Update login logic: try bcrypt first, fall back to old hash, rehash on success. (4) Set migration deadline (90 days) - after that, force password reset for unmigrated users. (5) Monitor migration progress - send email reminders to inactive users. Alternative (all at once): Force password reset for all users - disruptive but immediate security improvement. Temporary wrapper: bcrypt(sha256(password)) - allows migration without waiting for logins, but less secure than pure bcrypt. Never: Keep using MD5/SHA indefinitely - if you have a database leak, those passwords are compromised. Tools: Libraries like Django, Rails have built-in migration support. Bcrypt is backward compatible - can check multiple hash types during transition.
Programming Language Bcrypt Examples
- JavaScript/Node.js: const bcrypt = require("bcrypt"); const hash = await bcrypt.hash(password, 12); const match = await bcrypt.compare(password, hash);
- Python: import bcrypt; hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(12)); bcrypt.checkpw(password.encode(), hashed)
- Java: import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; encoder = new BCryptPasswordEncoder(12); hash = encoder.encode(password);
- C#: using BCrypt.Net; string hash = BCrypt.HashPassword(password, 12); bool verified = BCrypt.Verify(password, hash);
- PHP: $hash = password_hash($password, PASSWORD_BCRYPT, ["cost" => 12]); password_verify($password, $hash);
- Ruby: require "bcrypt"; password = BCrypt::Password.create("secret", cost: 12); password == "secret" # true
- Go: import "golang.org/x/crypto/bcrypt"; hash, _ := bcrypt.GenerateFromPassword([]byte(password), 12); bcrypt.CompareHashAndPassword(hash, []byte(password))
- Rust: use bcrypt::{hash, verify}; let hashed = hash(password, 12).unwrap(); verify(password, &hashed).unwrap();
- Swift: // Use CryptoKit or third-party library like BCryptSwift
- Database: Most apps hash in application layer, but PostgreSQL has pgcrypto extension: crypt(password, gen_salt('bf', 12))
Frequently Asked Questions
Why should I use bcrypt instead of SHA256 for passwords?
SHA256 is designed to be fast (billions of hashes per second on modern GPUs), making it terrible for passwords - attackers can try billions of password guesses per second. Bcrypt is intentionally slow (hundreds of hashes per second), making brute-force attacks impractical. With cost=12, bcrypt takes ~300ms per hash. An attacker trying common passwords would take years instead of minutes. Additionally, bcrypt auto-generates a unique salt for each password, preventing rainbow table attacks. SHA256 requires manual salt management and can be accelerated with GPUs. Bcrypt is memory-hard, resistant to ASIC/GPU speedup. For password storage, always use bcrypt, Argon2, or scrypt - never SHA256, MD5, or other fast hash functions.
What cost factor should I use for bcrypt?
Recommended: Cost 12 for general web applications (takes ~250-500ms per hash on modern servers). Use cost 10-11 if you have high login volume or slow servers. Use cost 14+ for administrative accounts or highly sensitive systems. Test on your server: run bcrypt with different costs and measure time - aim for 250-500ms sweet spot. Lower than 10 is vulnerable to GPU attacks. Higher than 15 might create user experience issues (slow logins) or DoS vulnerabilities. Increase cost every 2-3 years as hardware improves - Moore's Law means today's cost 12 will be cost 10 equivalent in a few years. Most frameworks default to 10 but 12 is better for 2026. Remember: each +1 doubles the time, so 12 is 4x slower than 10.
Can I hash passwords in JavaScript before sending to server?
Don't do it! Client-side hashing doesn't improve security and can actually weaken it. Problems: (1) Attacker can intercept the hash and replay it - server sees hash as "password". (2) Defeats rate limiting - attackers can pre-compute hashes offline. (3) Server compromise still exposes hashes that can be used directly. (4) JavaScript bcrypt is slow, freezes browser UI. (5) Gives false sense of security. Correct approach: Send password over HTTPS to server, hash server-side with bcrypt. HTTPS encrypts transmission, server-side hashing protects storage. The ONLY valid case for client hashing is zero-knowledge systems (like password managers), but that requires complex protocols, not simple bcrypt. For 99% of web apps, server-side bcrypt is the answer.
How do I verify a password against a bcrypt hash?
Use your language's bcrypt library compare/verify function - NEVER use simple string comparison (===, ==). Node.js: await bcrypt.compare(password, hash). Python: bcrypt.checkpw(password.encode(), hash). PHP: password_verify($password, $hash). Java: encoder.matches(password, hash). These functions are timing-safe (constant-time) to prevent timing attacks. They automatically extract the salt and cost from the hash string and recompute the hash with the same parameters, then compare. Never try to implement this yourself or use string comparison - it's vulnerable to timing attacks where attackers measure response time to guess passwords byte-by-byte. The bcrypt hash format ($2b$12$salt$hash) contains everything needed for verification - you don't store salt separately.
Should I add a pepper to bcrypt hashes?
Pepper is an application-wide secret added before hashing: bcrypt(password + pepper). Pros: If database is leaked but server code isn't, attackers can't crack passwords without the pepper. Adds defense in depth. Cons: Pepper must be stored somewhere accessible to app (environment variable, secrets manager). If code/config is leaked, pepper is exposed. Key rotation is difficult - must rehash all passwords. Recommendation: Bcrypt alone with adequate cost (12+) is sufficient for most applications. If you have specific high-security requirements (financial, healthcare, government), add pepper from secrets manager (AWS Secrets Manager, HashiCorp Vault). Store pepper separate from database. Rotate pepper periodically by supporting multiple peppers during transition (like key rotation). For most web apps, focus on proper bcrypt implementation, HTTPS, rate limiting, and breach detection rather than pepper.
How long does bcrypt hashing take and will it slow down my app?
With cost=12 on modern servers, bcrypt takes 250-500ms per hash. This is intentional and affects only password operations (registration, login, password reset). Impact: Login takes 250-500ms for password verification - users won't notice. Registration takes 250-500ms - one-time operation, acceptable. 100 concurrent logins = 100 bcrypt operations = still handled fine by multi-core servers. NOT affected: Regular API requests, database queries, page loads (password verification only on login). Mitigation: Use async bcrypt (await bcrypt.hash) to avoid blocking. Implement rate limiting (5 failed attempts = lockout) to prevent DoS via login spam. For very high-traffic login systems (millions/day), consider cost 10-11 instead of 12. Never use cost <10 for security reasons. Remember: 250ms is the security feature - it makes attacker's life hard. That's the entire point of bcrypt!
Can I upgrade from bcrypt cost 10 to cost 12 for existing users?
Yes! Implement transparent rehashing on successful login: (1) User logs in with password. (2) Verify against existing hash (cost 10). (3) If successful, check current cost (extract from hash $2b$10$...). (4) If cost < 12, generate new hash with cost 12. (5) Update database with new hash. (6) User never notices. Code: if (bcrypt.compare(password, oldHash)) { const rounds = parseInt(oldHash.split("$")[2]); if (rounds < 12) { const newHash = await bcrypt.hash(password, 12); updateDatabase(userId, newHash); } loginSuccess(); }. Over time (weeks/months), active users migrate to cost 12. Inactive users stay at cost 10 until next login. For critical systems, force password reset for users who haven't logged in after 90 days. This approach lets you increase security gradually without user disruption.
What's the difference between $2a$, $2b$, and $2y$ bcrypt versions?
$2a$ is the original bcrypt version (1999). $2b$ (2014) fixed a rare bug where passwords with null bytes were handled incorrectly. $2y$ is PHP-specific to work around the same bug. Recommendation: Always use $2b$ for new hashes - it's the current standard. All three are compatible for verification - bcrypt libraries handle all versions. You can verify $2a$ hashes with modern libraries, just generate new hashes with $2b$. The bug was extremely rare (passwords with \x00 bytes), so $2a$ hashes are still secure. Don't mass-migrate $2a$ to $2b$ - only upgrade on next successful login (lazy migration). If you see $2x$ or other variants, those are invalid - stick with $2a$, $2b$, or $2y$ (PHP). Modern bcrypt libraries default to $2b$ automatically, so you rarely need to specify version explicitly. Format: $version$cost$salthash - always 60 characters total.
How do I store bcrypt hashes in my database?
Use CHAR(60) or VARCHAR(72) column. Bcrypt hashes are always 60 characters ($2b$12$...), but VARCHAR(72) allows headroom for future algorithm versions that might be slightly longer. SQL: CREATE TABLE users (id INT, username VARCHAR(100), password_hash CHAR(60)); Never: Store password and hash together, store salt separately (bcrypt embeds salt in hash), use TEXT/BLOB (overkill, less efficient indexing). Insert: INSERT INTO users (username, password_hash) VALUES (?, ?) with hash generated by bcrypt.hash(). Query: SELECT password_hash FROM users WHERE username = ? then bcrypt.compare(password, hash). Indexing: Don't index password_hash column (no need to search by hash). Encryption: Encrypt database backups containing hashes. Some compliance regimes require application-layer encryption of password columns. Migration: If adding to existing schema, allow NULL initially, migrate users to bcrypt on login, eventually make NOT NULL.
Is bcrypt still secure in 2026 or should I switch to Argon2?
Bcrypt remains secure in 2026 with proper cost factor (12+). No practical attacks exist against bcrypt when used correctly. Bcrypt has 27 years of battle-testing and is the most widely supported password hashing algorithm. When to stick with bcrypt: Existing application with bcrypt - don't migrate unless you have specific new requirements. Wide library support needed across multiple languages. Proven, simple, understood by most developers. When to use Argon2: New high-security project starting from scratch. Need maximum resistance to GPU/ASIC attacks. Compliance requirements specifically call for Argon2. You have expertise to implement correctly. Bottom line: Bcrypt with cost 12+ is perfectly adequate for 99% of applications. If using bcrypt already, no need to change. If starting fresh in 2026 and security is paramount, consider Argon2id. Never downgrade from bcrypt to anything weaker (PBKDF2, SHA, MD5). Focus on correct implementation and adequate cost rather than algorithm choice.