The core difference: speed is a feature vs. a vulnerability
SHA-256 is a general-purpose cryptographic hash function. It is designed to be fast: a modern GPU can compute billions of SHA-256 hashes per second. That speed is exactly what you want when checksumming files or signing API requests.
bcrypt is a password-hashing function. It is designed to be slow: a configurable cost factor forces the algorithm to repeat its work 2^cost times. That slowness is the entire point. When an attacker steals your database and tries to crack passwords, making each attempt take 200ms instead of 0.0001ms is the difference between cracking a list in minutes vs. centuries.
How SHA-256 works
SHA-256 takes any input and produces a fixed 256-bit (64 hex character) digest. The same input always produces the same output. There is no salt, no randomness, and no way to make it slower.
Input: "hunter2" Output: f52fbd32b2b3b86ff88ef6c490628285f482af15ddcb29541f94bcf526a3f6c7 Input: "hunter3" Output: fb8c2e2b85ca81eb4350199faddd983cb26af3064614e737ea9f479621cfa57c
Notice: changing one character in the input produces a completely different output (the avalanche effect). But the same input will always produce the same hash, on any machine, forever. That determinism is essential for checksums and signatures, and catastrophic for password storage.
How bcrypt works
bcrypt generates a random 128-bit salt, then runs the Blowfish key schedule 2^cost times. The output encodes the algorithm version, cost, salt, and hash together in a single 60-character string.
Input: "hunter2" (cost: 12) Output: $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewdBPj4J/HS.iK9u Input: "hunter2" (cost: 12, different salt) Output: $2b$12$eImiTXuWVxfM37uY4JANjQ==.f9.E4QHvRtidDXhxCYZNxzTe7Dm.
Notice: the same password hashed twice produces two different outputs because a fresh random salt is generated each time. Verifying a password means re-running bcrypt with the stored hash (which contains the salt) and comparing the result. You never need to store the salt separately.
Side-by-side comparison
| Aspect | SHA-256 | bcrypt |
|---|---|---|
| Designed for | Data integrity, checksums, digital signatures | Password storage only |
| Speed | Very fast (billions/sec on GPU) | Intentionally slow (tunable) |
| Salt | None built in | Built in, random per hash |
| Output length | 256 bits (64 hex chars) | 60-char encoded string |
| Same input, same output | Always | No (random salt each time) |
| Cost factor | Fixed | Configurable (2^cost rounds) |
| Input size limit | Unlimited | Truncated at 72 bytes |
| GPU cracking resistance | Poor | Good |
When to use each
Use SHA-256 for
- ‣File integrity: verify a download was not corrupted or tampered with.
- ‣Digital signatures: sign commits, certificates, and API payloads.
- ‣Content addressing: Git object IDs, cache keys, ETags, deduplication.
- ‣HMAC: authenticate API requests using a shared secret.
- ‣Any non-secret data where speed and determinism matter.
Use bcrypt for
- ‣Storing user passwords in a database.
- ‣Verifying a login attempt against a stored hash.
- ‣Any secret that a human types and you need to compare later.
Frequently asked questions
Why is SHA-256 dangerous for passwords?
SHA-256 is designed to be fast. Modern GPUs can compute billions of SHA-256 hashes per second. An attacker who steals your database can try every word in a dictionary, every common password, and billions of variations in minutes. bcrypt's cost factor forces each attempt to take milliseconds on the attacker's hardware, making the same attack take years.
What is a rainbow table and does bcrypt protect against it?
A rainbow table is a precomputed lookup of hash to plaintext. An attacker hashes every common password in advance, then looks up any stolen hash instantly. bcrypt's built-in random salt means two users with the same password get different hashes, making precomputed tables useless. SHA-256 without a salt offers no such protection.
What cost factor should I use for bcrypt?
Pick a cost factor that makes hashing take 100 to 300ms on your server hardware. Cost 10 to 12 is typical for most web apps in 2026. Higher is more secure but increases login time. Re-evaluate every few years as hardware gets faster: you can re-hash passwords on next login without forcing a reset.
What is Argon2 and should I use it instead of bcrypt?
Argon2 won the 2015 Password Hashing Competition and is the current recommended choice for new systems. It is memory-hard (attackers need RAM, not just CPU/GPU), has configurable parallelism, and has no 72-byte input limit. If your language or framework supports Argon2id, prefer it. bcrypt remains secure and is widely supported, so there is no urgent need to migrate existing systems.
Can I use bcrypt for API tokens or session IDs?
No. bcrypt's 72-byte limit and intentional slowness make it wrong for tokens. For API tokens and session IDs, generate a cryptographically random value (at least 128 bits), then store a SHA-256 hash of it in the database. On each request, hash the incoming token and compare to the stored hash.
Is MD5 or SHA-1 ever acceptable for passwords?
No. MD5 and SHA-1 have practical collision attacks and are even faster than SHA-256 to crack. They should never be used for passwords, even with a salt. If you have a legacy system using MD5 or SHA-1 for passwords, migrate to bcrypt or Argon2 as soon as possible.