Home/Blog/bcrypt Password Hashing: Why It's Better Than MD5 & SHA-256 (Free Tool)
developer

bcrypt Password Hashing: Why It's Better Than MD5 & SHA-256 (Free Tool)

May 19, 20267 min readPublished by FluxToolkit Team

Every application that stores passwords faces the same security requirement: passwords must never be stored in plaintext, and they must be stored in a way that makes bulk cracking computationally impractical even if the database is stolen.

MD5 and SHA-256 are fast cryptographic hash functions — which makes them terrible for passwords. bcrypt was specifically designed to be slow, and that slowness is the entire point.


Generate a bcrypt Hash

Featured Utility

bcrypt Hash Generator

Hash passwords using bcrypt.

Try bcrypt Hash Generator


Why Fast Hashes Are Dangerous for Passwords

MD5, SHA-1, SHA-256, and SHA-512 are designed for speed. A modern GPU can compute:

  • MD5: ~40 billion hashes per second
  • SHA-256: ~10 billion hashes per second
  • bcrypt (cost 12): ~250 hashes per second

This speed difference is catastrophic for password security. If an attacker obtains your database, they can run dictionary attacks and rainbow table attacks against fast hashes at billions of attempts per second. An 8-character password can be cracked via brute force in seconds to minutes against MD5.

Against bcrypt at cost 12, the same attack takes years to centuries on the same hardware.


How bcrypt Works

bcrypt was designed in 1999 by Niels Provos and David Mazières specifically for password hashing. It has three key properties:

1. Adaptive Cost Factor

bcrypt includes a work factor (cost factor) — an integer that controls how many iterations of hashing occur. Every increment doubles the computation time.

Cost Approx. Time (modern server) Hashes/sec (GPU attack)
10 ~100ms ~1,000
12 ~400ms ~250
14 ~1.5s ~63
16 ~6s ~16

As hardware gets faster, you increase the cost factor — keeping the protection proportional to computing power growth.

2. Built-in Salt

bcrypt generates a unique random 128-bit salt for every hash automatically. This means two identical passwords produce completely different hash strings:

Password: "hunter2"
Hash 1: $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewqxaX9ov
Hash 2: $2b$12$eImiTXuWVxfM37uY4JANjQ.X9YKfGGmFIDSMa2L4T7q6k

Both verify correctly against "hunter2" even though they look entirely different. No rainbow table can be precomputed because the salt is embedded in the hash itself.

3. Fixed Output Length

bcrypt always produces a 60-character string regardless of input length, making storage simple and consistent.


Reading a bcrypt Hash

A bcrypt hash looks like this:

$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewqxaX9ovXZTx26

Breaking it down:

$2b$    → bcrypt algorithm version (2b is current)
12$     → Cost factor
LQv3c1yqBWVHxkd0LHAkCO → 22-char salt (Base64 encoded)
Yz6TtxMQJqhN8/LewqxaX9ovXZTx26 → 31-char hash

Everything needed to verify a password is embedded in the single hash string — no separate salt storage required.


bcrypt vs the Alternatives

Algorithm Designed For Password Use Notes
MD5 Checksums ❌ Never 40B hashes/sec on GPU; completely insecure
SHA-256 Data integrity ❌ Never Fast by design; no salt, no cost factor
SHA-512 Data integrity ❌ Never Same problem as SHA-256, just longer
bcrypt Password hashing ✅ Yes Adaptive cost, built-in salt
scrypt Password hashing ✅ Yes Also memory-hard; good alternative
Argon2 Password hashing ✅ Yes (recommended) Winner of PHC; memory-hard; newest standard
PBKDF2 Key derivation ✅ Acceptable NIST-approved; used in many standards

Recommendation hierarchy: Argon2id > bcrypt > scrypt > PBKDF2. Avoid MD5 and SHA for passwords entirely — there is no acceptable use case.


Implementation Examples

Node.js (bcryptjs)

const bcrypt = require('bcryptjs');

// Hash a password
const saltRounds = 12;
const hash = await bcrypt.hash(password, saltRounds);

// Verify a password
const isValid = await bcrypt.compare(inputPassword, storedHash);

Python (bcrypt)

import bcrypt

# Hash
hashed = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt(rounds=12))

# Verify
is_valid = bcrypt.checkpw(input_password.encode('utf-8'), hashed)

PHP

// Hash
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);

// Verify
$isValid = password_verify($inputPassword, $hash);

Choosing the Right Cost Factor

The rule: choose the highest cost factor that keeps login time under 100–400ms on your production server. Too slow and it becomes a denial-of-service vector (an attacker floods login requests, consuming server resources).

Testing approach:

const start = Date.now();
await bcrypt.hash('test', 12);
console.log(`Cost 12: ${Date.now() - start}ms`);

Aim for 200–400ms. If your server is powerful enough to do cost 14 in 400ms, use 14. Revisit the cost factor as hardware improves.


Common Mistakes

Hashing the hash: Never run bcrypt output through another hash function. The output of bcrypt is already the secure stored form.

Pre-hashing with SHA-256: Some implementations hash the password with SHA-256 before bcrypt to handle bcrypt's 72-character input limit. This is generally unnecessary for typical passwords but can help for very long passphrases.

Using cost 10 in 2026: Cost 10 was a reasonable default in 2011. With 2026 hardware, use at least 12, ideally 13–14.

Storing salts separately: bcrypt embeds the salt in the hash string. No separate salt column is needed.


Privacy Note

FluxToolkit's bcrypt generator runs entirely in your browser. The passwords you test are never transmitted to our servers. bcrypt hashing is performed client-side using JavaScript — your input stays on your device.


Frequently Asked Questions

Can I crack a bcrypt hash?

Bcrypt hashes cannot be reversed (cracked) directly — hashing is one-way. Attackers can only attack by guessing the original password and comparing. With cost 12, a GPU manages ~250 guesses per second, making brute force impractical for strong passwords.

Is bcrypt still the best choice in 2026?

Argon2id is now the recommended algorithm for new implementations (it won the Password Hashing Competition in 2015). However, bcrypt is still highly secure and widely supported. Using bcrypt correctly is far better than using Argon2id incorrectly.

What is bcrypt's 72-character limit?

bcrypt only processes the first 72 bytes of the input. Passwords or passphrases longer than 72 bytes are silently truncated. This is rarely a problem for typical passwords but should be noted for passphrase-based authentication.

Should I salt before bcrypt?

No. bcrypt generates its own random salt automatically. Adding your own salt before bcrypt provides no additional security and adds complexity without benefit.

Does FluxToolkit store passwords I hash?

No. Everything runs client-side in your browser. No input is transmitted to or stored on our servers.


Related Articles

FluxToolkit Editorial Team

Verified Author

A professional collective of software engineers, SEO marketing strategists, and UI/UX design specialists. We craft exhaustive, privacy-first technical guides to simplify offline browser processing, image rendering optimizations, and dev-ops analytics configurations for teams and creators worldwide.

Related Utilities

Share Guide

Found this helpful? Share this browser-side utility guide with your network.