Cryptography

Bcrypt vs SHA-256 for Password Storage: Which Is Actually Secure?

9 min read
By
Bcrypt vs SHA-256 for Password Storage: Which Is Actually Secure?

Photo by Tima Miroshnichenko from Pexels

SHA-256 is one of the most widely used hash functions in the world. It secures blockchain transactions, verifies file integrity, and underlies HMAC for API authentication. It is cryptographically sound, well-studied, and recommended by NIST. But when it comes to storing passwords, SHA-256 is the wrong tool. Not because it is broken, but because it is fast. And for password storage, speed is the enemy.

Let's look at why SHA-256 fails for password storage and why bcrypt succeeds.

The Fundamental Difference: Speed

The core difference between SHA-256 and bcrypt is their design goal:

**SHA-256** is a general-purpose hash function designed to be as fast as possible. It processes data quickly so you can hash large files, verify integrity, and build high-performance systems. On a modern GPU, SHA-256 can compute approximately 2.5 billion hashes per second.

**Bcrypt** is a password hashing function designed to be deliberately slow. It takes a configurable amount of time per hash (typically 100-400 milliseconds) to make password cracking impractical. On the same GPU, bcrypt at cost factor 12 computes approximately 2-3 hashes per second.

That difference is not incremental. It is a factor of roughly 1 billion. And that factor is the difference between "every weak password is cracked in seconds" and "the attack is not worth attempting."

The Attack Scenario

To understand why speed matters, consider what happens when an attacker steals a database of password hashes. They have the hashes but not the passwords. To recover the passwords, they try candidate passwords, hash them, and compare the results to the stolen hashes.

Let's say the attacker tries the top 10,000 most common passwords against a database of 1 million users:

**With SHA-256:** - 10,000 guesses x 1 million users = 10 billion hashes - At 2.5 billion hashes per second, this takes about 4 seconds - Every weak password in the database is cracked before you finish your coffee

**With bcrypt (cost 12):** - 10,000 guesses x 1 million users = 10 billion hashes - At 3 hashes per second, this takes about 105 years - The attacker will move on to an easier target

The difference is not a matter of degree. It is the difference between a trivial attack and an impractical one. This is why the hash function choice is the single most important decision in password storage.

Why a Salt Does Not Fix SHA-256

A common argument is: "I use SHA-256 with a unique salt per password, so I am secure." A salt is necessary, but it does not solve the speed problem.

A salt prevents rainbow tables and makes identical passwords produce different hashes. These are important benefits. But a salt does not slow down the hash computation. With SHA-256 and a salt, the attacker can still try 2.5 billion password guesses per second per GPU. They just need to use each user's salt for that user's hash.

The salt means the attacker cannot use a precomputed rainbow table. But they can still run a dictionary attack or brute force attack at full speed. The salt makes the attack per-user instead of per-database, but the per-user attack is still blazingly fast.

For a single user with a salted SHA-256 hash, the attacker can try 2.5 billion passwords per second. A 6-character lowercase password (308 million combinations) is cracked in 0.12 seconds. The salt did not help. The speed killed security.

Bcrypt's Design: Slowness as a Feature

Bcrypt was designed by Niels Provos and David Mazières in 1999 specifically to address the shortcomings of fast hash functions for password storage. Its key innovations are:

**Deliberate slowness.** Bcrypt takes a configurable amount of time per hash, controlled by the cost factor. At cost 12, each hash takes about 400 milliseconds. This is fast enough for legitimate logins (users do not notice 400ms) but slow enough to make large-scale cracking impractical.

**Built-in salt.** Bcrypt generates a random salt automatically and embeds it in the hash string. You do not need to manage salts separately. The salt is part of the output, so storing the hash means storing the salt.

**Adaptive cost.** The cost factor can be increased over time as hardware improves. When GPUs get twice as fast, you bump the cost factor by one and bcrypt is back to the same level of security. No algorithm change, no data migration, just a configuration update.

These three properties together make bcrypt dramatically more secure than SHA-256 for password storage. For a deeper look at how bcrypt works, see our bcrypt explained guide.

The Numbers Side by Side

Here is a comparison of SHA-256 and bcrypt on a single modern GPU:

| Property | SHA-256 | Bcrypt (cost 12) | |---|---|---| | Hashes per second (GPU) | 2.5 billion | 2-3 | | Time to try 10,000 passwords | 4 microseconds | 50 minutes | | Time to crack 6-char lowercase | 0.12 seconds | 3 years | | Built-in salt | No (must manage manually) | Yes (automatic) | | Adjustable speed | No (fixed speed) | Yes (cost factor) | | Designed for | General-purpose hashing | Password hashing |

The speed difference is the entire story. SHA-256 is not broken. It is not weak. It is simply the wrong tool for the job. Using SHA-256 for passwords is like using a race car for a school zone. The speed that makes it excellent for its intended purpose makes it dangerous for this specific use case.

When SHA-256 Is the Right Choice

To be clear, SHA-256 is an excellent hash function for many purposes:

- **File integrity verification.** You want to quickly verify that a file was not corrupted. Speed is good here. - **HMAC computation.** HMAC-SHA256 is the standard for message authentication. Speed is desirable and security comes from the key, not the slowness. - **Blockchain and cryptocurrency.** SHA-256 is used in Bitcoin and other systems where fast hashing is needed. - **Digital signatures.** SHA-256 is used as the hash function in RSA and ECDSA signatures. - **Certificate fingerprints.** SHA-256 fingerprints identify TLS certificates.

In all these cases, the input is not a human-chosen password. It is a file, a message, or a cryptographic key. The attacker cannot try "common" values because the input space is too large. Speed is an advantage, not a vulnerability.

The problem is specifically human-chosen passwords, which have low entropy (people choose predictable passwords) and are therefore vulnerable to guessing attacks. Slow hashing is the defense against low entropy.

Migrating from SHA-256 to Bcrypt

If your database currently uses SHA-256 for password storage, you should plan a migration to bcrypt or Argon2id. The good news is you can do this without resetting everyone's passwords.

The standard migration strategy is:

1. When a user logs in, verify their password against the existing SHA-256 hash. 2. If verification succeeds, re-hash the password with bcrypt and store the new bcrypt hash. 3. Gradually, as users log in, the database migrates from SHA-256 to bcrypt. 4. Users who never log in again keep their SHA-256 hash, which is a lower security level but acceptable for inactive accounts.

This approach requires no password resets, no user communication, and no downtime. It happens transparently as part of the normal login flow. For more details on this process, see our bcrypt explained post.

The Bottom Line

SHA-256 is a superb hash function. It is also a terrible password hashing function. The speed that makes it excellent for general-purpose hashing makes it dangerous for password storage. When an attacker steals a SHA-256 password database, they can crack weak passwords at billions of guesses per second.

Bcrypt solves this by being deliberately slow. At cost 12, it takes 400 milliseconds per hash, which is imperceptible for legitimate logins but devastating for attackers. It also handles salting automatically and can be made slower over time as hardware improves.

If you are storing passwords with SHA-256, migrate to bcrypt. If you are starting a new project, use bcrypt from the beginning. The choice is not about cryptographic strength (both are unbroken). It is about speed, and for passwords, slower is more secure.

To see the difference for yourself, try our password hash generator to hash the same password with both SHA-256 and bcrypt, and compare the output and timing. And for a complete guide to how bcrypt works, read our bcrypt explained post.

Frequently Asked Questions

Why is SHA-256 bad for password storage?

SHA-256 is designed to be fast. A modern GPU can compute 2.5 billion SHA-256 hashes per second. When an attacker steals a database of SHA-256 password hashes, they can try billions of password guesses per second, cracking weak passwords in seconds. Bcrypt is designed to be slow, computing only 2-3 hashes per second at cost 12, making the same attack take years.

Can I make SHA-256 secure for passwords by adding a salt?

A salt helps by preventing rainbow tables and identical-password detection, but it does not solve the fundamental problem: SHA-256 is too fast. Even with a salt, an attacker can try 2.5 billion password guesses per second per GPU. A salt is necessary but not sufficient. You also need a slow hash function. SHA-256 with a salt is still crackable at billions of guesses per second.

Is bcrypt always better than SHA-256 for passwords?

Yes, for password storage specifically. SHA-256 is excellent for other uses (file integrity, blockchain, digital signatures, HMAC) where speed is desirable. But for passwords, the speed is the vulnerability. Bcrypt is designed specifically for password hashing: it is slow, it uses a salt automatically, and its cost factor can be increased over time as hardware improves.

What should I do if my database uses SHA-256 for passwords?

Plan a migration to bcrypt or Argon2id. The standard approach is to keep the SHA-256 hash as the input to bcrypt: when a user logs in, verify their password against the SHA-256 hash, then re-hash the password with bcrypt and store the new hash. This gradually migrates users as they log in without requiring a password reset. See our bcrypt explained guide for migration details.

Try NovelCrypt Tools

Experience military-grade encryption for your sensitive data. Create self-destructing messages, encrypt files, or explore our experimental lab tools.

Explore NovelCrypt