Perbedaan SHA256 dan bcrypt: Panduan Lengkap Memilih Algoritma Hashing yang Tepat

Banyak developer yang bingung milih antara SHA256 dan bcrypt buat nyimpen password. Padahal kedua algoritma ini punya tujuan berbeda dan salah pilih bisa berakibat fatal buat keamanan aplikasi. Artikel ini bakal ngebahas perbedaan mendasar, kapan pake yang mana, dan kenapa bcrypt jauh lebih aman buat password hashing.

Perbedaan Fundamental: Tujuan Desain

Sebelum masuk ke detail teknis, penting buat paham filosofi desain kedua algoritma ini.

AspekSHA256bcrypt
Tujuan utamaData integrity, checksumPassword hashing
KecepatanCepat (by design)Lambat (by design)
SaltTidak built-inBuilt-in otomatis
AdaptiveTidak (fixed algorithm)Ya (adjustable cost)
Resistensi brute-forceRendahTinggi

Key Insight: SHA256 dibuat buat verifikasi integritas data (file checksum, digital signature), sementara bcrypt dibuat khusus buat melindungi password dari brute-force attacks.

1. Cara Kerja dan Karakteristik

SHA256 (Secure Hash Algorithm 256-bit)

SHA256 adalah cryptographic hash function dari keluarga SHA-2 yang dirancang oleh NSA. Outputnya selalu 256-bit (64 karakter hex) regardless input size.

# Contoh hash SHA256
echo -n "password123" | sha256sum
# Output: ef92b768b6b9e1b6b5e1e3c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8

# Karakteristik:
# - Selalu 64 karakter hex
# - Deterministic: input sama = output sama
# - Cepat: jutaan hash per detik di GPU modern

Karakteristik SHA256:

  • Deterministic: Hash yang sama selalu menghasilkan output yang sama
  • One-way: Tidak bisa reverse dari hash ke original input
  • Avalanche effect: Perubahan 1 bit input mengubah sebagian besar output
  • Collision resistant: Sulit menemukan dua input dengan hash sama

bcrypt (Blowfish Crypt)

bcrypt adalah adaptive hashing algorithm yang berbasis cipher Blowfish. Outputnya tidak fixed length dan mengandung salt serta cost factor.

# Contoh hash bcrypt
$2b$12$R9h/cIPz0gi.URNNX3kh2OPST9/PgBkqquzi.Ss7KIUgO2t0jWMUW

# Format: $2b$[cost]$[salt+hash]
# - $2b$: Algorithm identifier
# - 12: Cost factor (2^12 = 4096 iterasi)
# - 22 karakter: Salt (16 byte base64 encoded)
# - 31 karakter: Hash (24 byte base64 encoded)

Karakteristik bcrypt:

  • Salted: Setiap hash punya salt random yang unik
  • Adaptive: Cost factor bisa dinaikin seiring meningkatnya hardware
  • Slow by design: Sengaja lambat buat hindari brute-force
  • Self-contained: Semua parameter (salt, cost) ada di dalam hash string

2. Perbandingan Kecepatan: Mengapa Itu Penting

Kecepatan adalah perbedaan paling kritis. SHA256 terlalu cepat buat password hashing.

Benchmark Kecepatan

HardwareSHA256bcrypt (cost 12)
CPU Modern~1 juta hash/detik~50-100 hash/detik
GPU (RTX 4090)~10 miliar hash/detik~500-1000 hash/detik
FPGA/ASIC~100+ miliar hash/detikSulit diakselerasi
import hashlib
import bcrypt
import time

password = b"test_password"

# SHA256 speed test
start = time.time()
for _ in range(100000):
    hashlib.sha256(password).hexdigest()
sha_time = time.time() - start

# bcrypt speed test
start = time.time()
for _ in range(100):
    bcrypt.hashpw(password, bcrypt.gensalt(rounds=12))
bcrypt_time = time.time() - start

print(f"SHA256 100k hashes: {sha_time:.2f}s")
print(f"bcrypt 100 hashes: {bcrypt_time:.2f}s")
print(f"Perbandingan: SHA256 ~{int((sha_time/100000)/(bcrypt_time/100))}x lebih cepat")

Implikasi Keamanan

Skenario serangan brute-force:

PasswordSHA256 (GPU)bcrypt (cost 12)
password< 1 detik~2-3 hari
Password123~1 menit~3-6 bulan
P@ssw0rd!2024~1 hari~50+ tahun

Kesimpulan: SHA256 terlalu cepat buat password. Attacker bisa coba miliaran kombinasi per detik, sementara bcrypt membatasi ke ratusan percobaan per detik.

3. Perlindungan terhadap Rainbow Table

Rainbow table adalah precomputed table buat reverse hash. Ini ancaman besar buat password hashing.

SHA256: Rentan tanpa Salt

import hashlib

# Tanpa salt, hash yang sama selalu identik
common_passwords = ["password", "123456", "qwerty", "admin"]

# Attacker bisa precompute:
rainbow_table = {hashlib.sha256(p.encode()).hexdigest(): p for p in common_passwords}

# Ketika database bocor:
leaked_hash = "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8"

if leaked_hash in rainbow_table:
    print(f"Password found: {rainbow_table[leaked_hash]}")
    # Output: Password found: password

Solusi manual untuk SHA256 (tidak recommended):

import hashlib
import os

# Tambahkan salt manual (tetap kurang aman)
salt = os.urandom(32)  # 256-bit salt
password = b"user_password"
hash = hashlib.sha256(salt + password).hexdigest()

# Tapi tetap cepat dan tidak adaptive!

bcrypt: Proteksi Otomatis

import bcrypt

# Setiap hash punya salt unik yang beda-beda
hash1 = bcrypt.hashpw(b"password", bcrypt.gensalt())
hash2 = bcrypt.hashpw(b"password", bcrypt.gensalt())

print(hash1)  # $2b$12$abc...
print(hash2)  # $2b$12$xyz... (berbeda!)

# Rainbow table tidak efektif karena setiap entry unik

4. Use Case: Kapan Pake Apa?

Gunakan SHA256 untuk:

1. File Integrity / Checksum

# Verifikasi download tidak corrupt
sha256sum ubuntu-22.04.iso
# Compare dengan hash official

# Verify file integrity setelah transfer
sha256sum -c checksum.txt

2. Digital Signatures

import hashlib
import hmac

# HMAC dengan SHA256 untuk API authentication
secret_key = b"api_secret_key"
message = b"request_payload"

signature = hmac.new(secret_key, message, hashlib.sha256).hexdigest()
# Kirim signature bersama request untuk verifikasi integrity

3. Blockchain / Cryptocurrency

# Bitcoin mining menggunakan double SHA256
import hashlib

def double_sha256(data):
    return hashlib.sha256(hashlib.sha256(data).digest()).digest()

4. Certificate Fingerprinting

# SSL certificate fingerprint
openssl x509 -in cert.pem -noout -sha256 -fingerprint

Gunakan bcrypt untuk:

1. Password Storage (User Authentication)

import bcrypt

def register_user(email, password):
    # Hash password sebelum simpan ke DB
    hashed = bcrypt.hashpw(
        password.encode('utf-8'),
        bcrypt.gensalt(rounds=12)
    )
    save_to_database(email, hashed)

def login_user(email, password):
    stored_hash = get_hash_from_db(email)
    return bcrypt.checkpw(
        password.encode('utf-8'),
        stored_hash.encode('utf-8')
    )

2. API Key Hashing

# API key disimpan sebagai hash, bukan plaintext
api_key = generate_random_key()  # "ak_live_12345..."
hashed_key = bcrypt.hashpw(api_key.encode(), bcrypt.gensalt())

# Simpan hashed_key di DB, kirim api_key sekali ke user

3. Secure Token Hashing

# Reset password token, email verification token
token = generate_secure_token()
hashed_token = bcrypt.hashpw(token.encode(), bcrypt.gensalt(rounds=10))

# Simpan hashed_token di DB, kirim token ke email/user

5. Implementasi yang Salah vs Benar

❌ Salah: Pake SHA256 buat Password

import hashlib

class BadAuthSystem:
    def hash_password(self, password):
        # JANGAN LAKUKAN INI!
        return hashlib.sha256(password.encode()).hexdigest()
    
    def verify_password(self, password, stored_hash):
        return self.hash_password(password) == stored_hash

# Masalah:
# 1. Tidak ada salt -> rainbow table attack
# 2. Terlalu cepat -> brute force mudah
# 3. Tidak adaptive -> tidak bisa upgrade security

✅ Benar: Pake bcrypt buat Password

import bcrypt

class SecureAuthSystem:
    def hash_password(self, password: str) -> str:
        """Hash password dengan bcrypt"""
        return bcrypt.hashpw(
            password.encode('utf-8'),
            bcrypt.gensalt(rounds=12)
        ).decode('utf-8')
    
    def verify_password(self, password: str, stored_hash: str) -> bool:
        """Verify password dengan secure comparison"""
        return bcrypt.checkpw(
            password.encode('utf-8'),
            stored_hash.encode('utf-8')
        )
    
    def needs_rehash(self, stored_hash: str, new_cost: int = 14) -> bool:
        """Check apakah perlu rehash dengan cost lebih tinggi"""
        # Ambil cost dari stored hash
        cost = int(stored_hash.split('$')[2])
        return cost < new_cost

6. Alternatif Modern: Argon2

Selain bcrypt, ada algoritma terbaru yang direkomendasikan oleh PHC (Password Hashing Competition): Argon2.

FiturbcryptArgon2id
Memory hard❌ Tidak✅ Ya
GPU resistant⚠️ Sedang✅ Tinggi
Side-channel resistant⚠️ Partial✅ Ya
Winner PHC 2015
Recommendation✅ Good✅ Better
# Argon2 (lebih aman dari bcrypt untuk aplikasi baru)
import argon2

ph = argon2.PasswordHasher(
    time_cost=3,      # Iterations
    memory_cost=65536, # 64 MB
    parallelism=1
)

hash = ph.hash("user_password")
ph.verify(hash, "user_password")  # True

Rekomendasi: Untuk aplikasi baru, pertimbangkan Argon2id. Untuk sistem existing, bcrypt masih sangat aman dan lebih widely supported.

7. Checklist Keputusan

Gunakan diagram keputusan ini buat milih algoritma:

Apakah data yang di-hash adalah password/user credential?
├── YA → Gunakan bcrypt (atau Argon2)
│   └── Butuh adaptive cost? → bcrypt ✅
│   └── Butuh memory-hard? → Argon2 ✅
└── TIDAK → Apakah butuh kecepatan tinggi?
    ├── YA → SHA256 (data integrity, checksum)
    └── TIDAK → Pertimbangkan use case spesifik

8. Kesalahan Umum yang Harus Dihindari

1. Double Hashing (SHA256 + bcrypt)

# ❌ SALAH - Tidak menambah keamanan, malah bisa weaken
hashed = bcrypt.hashpw(sha256(password).digest(), salt)

# ✅ BENAR - bcrypt saja sudah cukup
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt())

2. Custom Crypto

# ❌ SALAH - Jangan bikin algoritma sendiri!
def my_hash(password):
    return sha256(password + "my_secret_salt")

# ✅ BENAR - Pake library teruji
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt())

3. Salt yang Tidak Cukup Random

# ❌ SALAH - Salt statis atau predictable
salt = "my_app_name_2024"  # Jangan!

# ✅ BENAR - Random cryptographically secure
salt = bcrypt.gensalt()  # 16 byte random

Kesimpulan

KriteriaPemenangKeterangan
Password hashingbcryptLambat, salted, adaptive
File integritySHA256Cepat, deterministic
Digital signaturesSHA256Standar industri
Future-proofingArgon2Memory-hard, PHC winner

Aturan emas:

  • Password/user credentials = bcrypt (atau Argon2)
  • Data integrity/checksum = SHA256
  • Jangan pernah pake SHA256 buat password storage
  • Jangan pernah pake bcrypt buat large data hashing

Pemilihan algoritma yang tepat adalah fondasi keamanan aplikasi. Salah pilih bisa membuat data pengguna rentan meski sistem lainnya sudah aman. Stay secure dan pilih tools yang tepat untuk job yang tepat

Leave a Reply

Your email address will not be published. Required fields are marked *