SHA-256 vs bcrypt for Password Security Guide

x32x01
  • by x32x01 ||
  • #1
Imagine you're reviewing code written by two backend engineers.
Both are responsible for storing user passwords.
At first glance, their implementations seem secure.

Engineer A 👇
Python:
import hashlib

password = "SuperSecret123"
hashed_password = hashlib.sha256(password.encode()).hexdigest()

print(hashed_password)
Output:
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8

Engineer B 👇
Python:
const bcrypt = require('bcrypt');

const password = "SuperSecret123";
const hash = bcrypt.hashSync(password, 12);

console.log(hash);
Output:
$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW

Both developers claim they have secured user passwords.
Both outputs look random.
Both seem impossible to read.

So here's the interview question:
❓ If the database is leaked tomorrow, which implementation would you approve?
And more importantly...
❓ Why?



The First Mistake: Passwords Are Not "Encrypted" 🔥​

One of the most common misconceptions in software development is calling password storage "encryption."
Passwords should not be encrypted.
They should be hashed.
Why?

Because encryption is reversible.
If an attacker gains access to the encryption key, they can recover every password instantly.
Hashing works differently.
A hash function converts data into a fixed-length output that cannot be directly reversed.
That's why modern authentication systems store password hashes rather than plaintext passwords.



Why SHA-256 Looks Secure But Isn't 🚨​

Many developers see SHA-256 and assume it is automatically secure.
After all, SHA-256 is used in:
✅ Digital signatures​
✅ Blockchain systems​
✅ File integrity verification​
✅ Certificates​
✅ Security protocols​
The algorithm itself is extremely secure.
The problem is not SHA-256.
The problem is using SHA-256 for password storage.

SHA-256 Is Extremely Fast​

Modern CPUs and GPUs can calculate billions of SHA-256 hashes every second.
For password storage, that's actually bad.
Very bad.

If an attacker steals a database containing SHA-256 password hashes, they can launch massive offline attacks using:
⚡ Dictionary attacks​
⚡ Brute-force attacks​
⚡ Rainbow tables​
⚡ GPU-accelerated cracking tools​

For example:
Python:
import hashlib

candidate = "password123"

hash_value = hashlib.sha256(candidate.encode()).hexdigest()

print(hash_value)
An attacker can run this process billions of times until a matching password is found.
That's why leaked SHA-256 password databases are often cracked surprisingly quickly.



The Real Problem: Users Choose Weak Passwords​

Developers often assume users create strong passwords.
Reality says otherwise.

Many users still choose passwords like:
123456
password
qwerty
admin123
welcome1
Even if these passwords are hashed with SHA-256, attackers can test them almost instantly.
The hash algorithm may be secure.
Human behavior is not.



Why bcrypt Was Designed Specifically for Passwords 🛡️​

Unlike SHA-256, bcrypt was created specifically for password hashing.
Its design focuses on making password cracking painfully slow.
That single difference changes everything.

bcrypt Uses Salting Automatically​

Every password receives a unique random salt.
Example:
Python:
bcrypt.hash("password", 12)
User A: $2b$12$abc...
User B: $2b$12$xyz...
Even if both users have the exact same password, their stored hashes will be completely different.
This eliminates the effectiveness of rainbow tables.



bcrypt Is Intentionally Slow ⏳​

This is the feature that makes bcrypt powerful.
With bcrypt:
Python:
bcrypt.hash(password, 12);
The cost factor (12) forces the system to spend computational time generating the hash.

A legitimate login might take: 🕒 100–300 milliseconds
A user never notices.
But an attacker attempting billions of guesses certainly does.
Instead of testing billions of passwords per second, they may only test thousands.
That difference can turn a breach from hours into years.



Understanding the Cost Factor​

One of bcrypt's biggest advantages is its adjustable work factor.
Example:
Python:
bcrypt.hash(password, 10);
bcrypt.hash(password, 12);
bcrypt.hash(password, 14);
As hardware becomes faster, organizations can increase the cost factor.
This allows password security to evolve alongside computing power.
SHA-256 offers no such protection.



Real-World Attack Scenario 🎯​

Imagine two databases are leaked.

Database A​

SHA256(password)

Database B​

bcrypt(password, cost=12)
An attacker obtains both databases.

For Database A:
⚠️ Billions of guesses per second.​
⚠️ Massive GPU acceleration.​
⚠️ Common passwords cracked quickly.​
⚠️ Credential stuffing attacks become possible.​

For Database B:
✅ Each guess is computationally expensive.​
✅ Every password has a unique salt.​
✅ Rainbow tables become useless.​
✅ Cracking becomes significantly more difficult and expensive.​
The difference is dramatic.

What Would a Senior Backend Engineer Approve?​

The correct answer is:
✅ Engineer B
Because bcrypt was specifically designed for password storage.
Engineer A used a cryptographic hash function.
Engineer B used a password hashing function.
Those are not the same thing.
A senior engineer understands that password security is not about producing a random-looking string.
It's about making offline password cracking economically impractical.



Modern Alternatives to bcrypt​

Today, security professionals may also recommend:
🔹 bcrypt
🔹 Argon2
🔹 scrypt
Among these options, many experts consider Argon2 the current gold standard because it provides memory-hard protection against modern hardware attacks.
However, bcrypt remains widely trusted and is still a strong choice for production systems.



Best Practices for Secure Password Storage​

If you're building authentication systems, follow these guidelines:
✅ Never store plaintext passwords.​
✅ Never use MD5 for passwords.​
✅ Never use SHA-1 for passwords.​
✅ Avoid raw SHA-256 for password storage.​
✅ Use bcrypt, scrypt, or Argon2.​
✅ Enforce strong password policies.​
✅ Enable multi-factor authentication (MFA).​
✅ Monitor for credential stuffing attacks.​



Final Answer​

If the database leaks tomorrow, I would approve Engineer B's implementation using bcrypt.
Not because the hash looks more complex.
Not because it's newer.
But because bcrypt was designed to solve the exact problem we face after a database breach:
Making password cracking slow, expensive, and impractical for attackers.
That's the difference between using cryptography...
And using the right cryptography. 🔐
 
Related Threads
x32x01
Replies
0
Views
743
x32x01
x32x01
x32x01
Replies
0
Views
170
x32x01
x32x01
x32x01
Replies
0
Views
126
x32x01
x32x01
x32x01
Replies
0
Views
125
x32x01
x32x01
Register & Login Faster
Forgot your password?
Forum Statistics
Threads
977
Messages
984
Members
75
Latest Member
Cripto_Card_Ova
Back
Top