Secure Password Hashing with Bcrypt: A Developer's Guide

Security

Why Bcrypt?

Bcrypt is the gold standard for password hashing because of its adaptive cost factor. As hardware gets faster, you increase the rounds parameter to make each hash slower — without changing any application code or re-hashing existing passwords.

SHA-256 and MD5 are fast by design, which makes them dangerously easy to brute-force when used for passwords. Bcrypt is deliberately slow.

How It Works

  1. A random 16-byte salt is generated per password
  2. The password is combined with the salt and hashed using the Blowfish cipher
  3. The hash includes the salt and cost factor, producing a single portable string:
$2b$12$LQv3c1yqBWVHxkd0LHAkCO...
 ^  ^  ^
 |  |  salt (22 chars)
 |  cost factor (12 = 2^12 rounds)
 version

Using the API

Hash a password:

curl -X POST https://api.toolkitapi.io/v1/devtools/bcrypt-hash \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"password": "hunter2", "rounds": 12}'
{ "hash": "$2b$12$LQv3c1yqBWVHxkd0LHAkCOvx1lTLH0N5..." }

Verify a password:

curl -X POST https://api.toolkitapi.io/v1/devtools/bcrypt-verify \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"password": "hunter2", "hash": "$2b$12$..."}'
{ "match": true }

Choosing a Cost Factor

Rounds Approx time (modern CPU) Recommended for
10 ~100ms High-traffic endpoints
12 ~400ms Standard user login
14 ~1.5s High-value accounts

OWASP currently recommends a minimum of rounds=10. Use 12 as a safe default.

Common Mistakes

  • Truncating passwords — bcrypt silently truncates inputs beyond 72 bytes. Pre-hash with SHA-256 if you need to support longer passwords.
  • Reusing salts — the API always generates a fresh salt; never supply your own.
  • Comparing hashes directly — always use constant-time comparison (verify endpoint), never ==.

Try it out

Browse Tools →

More from the Blog