Published: May 26, 2026
If your application stores passwords in plain text, a single database breach exposes every user's credentials. Attackers don't just use stolen passwords on your site β they try them on email, banking, and social media accounts too. Password hashing solves this by converting passwords into irreversible, fixed-length strings. Even if an attacker steals the hash, they cannot reverse it back to the original password.
But not all hashing is equal. Fast algorithms like MD5 and SHA-256 were designed for integrity checking, not password storage. Modern password hashing must be deliberately slow and salted to resist brute-force and rainbow-table attacks. That's where bcrypt comes in.
bcrypt is a password hashing function designed by Niels Provos and David Mazières in 1999. It was built on the Blowfish cipher and incorporates three critical security features:
Today, bcrypt is the de facto standard for password storage in most web frameworks and is recommended by OWASP for applications that do not require FIPS compliance.
bcrypt uses the key schedule of the Blowfish cipher. When you hash a password, bcrypt:
2^cost rounds.A bcrypt hash looks like this:
$2b$10$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36PQm4sEPhMNPfE8iCu4z4C
βββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββ
β β ββ Hash output (31 characters, base-64 encoded)
β ββ Salt (22 characters, base-64 encoded)
ββ Cost factor (10 = 2^10 iterations)
The cost factor (often called "salt rounds" or "work factor") determines how many iterations bcrypt runs. The actual iteration count is 2^cost, so small increases have large effects:
As of 2026, cost factor 10 to 12 is the sweet spot for most web applications. Choose the highest value your server can tolerate without degrading the user experience.
Let's compare bcrypt with other algorithms:
Here's how to hash and verify passwords using bcrypt in Node.js:
const bcrypt = require('bcrypt');
const saltRounds = 12;
async function hashPassword(plainPassword) {
const salt = await bcrypt.genSalt(saltRounds);
const hash = await bcrypt.hash(plainPassword, salt);
return hash;
}
async function verifyPassword(plainPassword, hash) {
const match = await bcrypt.compare(plainPassword, hash);
return match; // true or false
}
// Usage
const hash = await hashPassword('mySecureP@ss!');
console.log(hash); // $2b$12$...
const isValid = await verifyPassword('mySecureP@ss!', hash);
console.log(isValid); // true
Python's bcrypt library works similarly:
import bcrypt
salt_rounds = 12
def hash_password(plain_password):
salt = bcrypt.gensalt(rounds=salt_rounds)
hashed = bcrypt.hashpw(plain_password.encode('utf-8'), salt)
return hashed.decode('utf-8')
def verify_password(plain_password, hashed):
return bcrypt.checkpw(
plain_password.encode('utf-8'),
hashed.encode('utf-8')
)
# Usage
hashed = hash_password('mySecureP@ss!')
print(hashed) # $2b$12$...
is_valid = verify_password('mySecureP@ss!', hashed)
print(is_valid) # True
Want to experiment with bcrypt without writing code? Use our free online bcrypt hash generator. You can instantly generate hashes with different cost factors, copy the results, and test verification. It's perfect for learning how bcrypt behaves or for quickly hashing a test password during development.
bcrypt remains one of the best choices for password hashing in 2026. Its adaptive cost factor, automatic salting, and resistance to GPU-based attacks make it a reliable foundation for authentication security. Whether you're building a Node.js API, a Python web app, or just learning about cryptography, understanding bcrypt is essential. Try our bcrypt hash generator online to see it in action β and remember: always salt your hashes!