Apa Itu Algoritma Hashing Bcrypt & Mengapa MD5/SHA Tidak Boleh Digunakan?
Bcrypt adalah fungsi hashing kata sandi adaptif satu arah (one-way adaptive cryptographic password hashing function) yang dirancang oleh ilmuwan komputer Niels Provos dan David Maziรจres pada tahun 1999 untuk sistem operasi OpenBSD. Algoritma ini dibangun berbasis sandi blok Eksblowfish (Extended Eksblowfish Key Setup) yang memiliki karakteristik komputasi intensif dan sengaja dirancang lambat untuk menggagalkan upaya peretasan massal berbasis hardware modern seperti GPU cluster dan ASIC rig.
Banyak pengembang web pemula melakukan kesalahan fatal dalam arsitektur keamanan dengan menyimpan kata sandi pengguna menggunakan algoritma MD5, SHA-1, atau SHA-256. Algoritma keluarga SHA dan MD5 dirancang sebagai general-purpose cryptographic hash yang dituntut berjalan secepat mungkin untuk keperluan verifikasi integritas data, checksum berkas biner, dan tanda tangan digital. Kecepatan komputasi super tinggi tersebut justru menjadi bencana besar saat diterapkan pada proteksi kata sandi pengguna.
MD5 / SHA-256 (Sangat Berbahaya untuk Password)
Sebuah kartu grafis modern (seperti NVIDIA RTX 4090) mampu menghitung lebih dari 150 miliar hash MD5 per detik atau 10 miliar hash SHA-256 per detik menggunakan alat peretas seperti Hashcat dan John the Ripper.
Dampak: Password 8 karakter kombinasi huruf dan angka dapat dijebol melalui serangan Brute-Force atau Rainbow Table dalam hitungan menit saja.
Bcrypt (Standar Industri Password Security)
Bcrypt menerapkan teknik Key Stretching dan Adaptive Cost Factor. Rig GPU canggih hanya mampu menghitung sekitar beberapa ribu hash Bcrypt per detik pada Cost Factor 10โ12 karena arsitektur eksblowfish yang membutuhkan akses memori cache L1/L2 secara intensif.
Dampak: Peretas membutuhkan ratusan hingga ribuan tahun untuk mencoba kombinasi kata sandi kamus.
Bagaimana Algoritma Bcrypt & Eksblowfish Bekerja di Balik Layar?
Arsitektur inti Bcrypt mengandalkan varian modifikasi dari cipher Blowfish bernama Eksblowfish (Extended Key Schedule Blowfish). Proses hashing dibagi menjadi tiga tahapan komputasi matematis yang ketat:
- Inisialisasi State Eksblowfish (P-Array & S-Boxes): Bcrypt menginisialisasi 18 buah subkey 32-bit (disebut P-Array) dan 4 buah Substitution Boxes (S-Boxes, masing-masing berisi 256 entri 32-bit) menggunakan angka pecahan konstanta heksadesimal dari bilangan Pi ($\pi$).
- EksblowfishSetup Loop (Key Stretching dengan Salt): Sistem menjalankan fungsi
EksblowfishSetup(cost, salt, password). Pada tahap ini, state internal dienkripsi berulang-ulang menggunakan kombinasi Salt 128-bit dan kata sandi pengguna sebanyak $2^{\text{cost}}$ putaran (rounds). Pada Cost Factor 10, proses key expansion ini diulang sebanyak 1.024 kali; pada Cost 12 diulang 4.096 kali. Hal ini memastikan bahwa pembuatan hash membutuhkan waktu CPU yang dapat dikontrol oleh pemilik server. - Enkripsi String Teks Tetap (Ciphertext Generation): Setelah state internal selesai diacak dan diperluas melalui ribuan putaran, algoritma menggunakan state tersebut untuk mengenkripsi string teks tetap berukuran 192-bit (24 karakter) berupa string ASCII:
"OrpheanBeholderScryDoubt"String ini dienkripsi sebanyak 64 kali berturut-turut dalam mode CBC (Cipher Block Chaining). Hasil 192-bit ciphertext inilah yang kemudian dikodekan ke dalam format Base64 khusus 31 karakter sebagai representasi akhir hash.
Anatomi dan Struktur Format String Hash Bcrypt (60 Karakter)
Setiap output hash yang dihasilkan oleh algoritma Bcrypt memiliki panjang persis 60 karakter ASCII yang terbagi menjadi empat segmen modular yang dipisahkan oleh karakter pembatas dolar ($). Seluruh informasi yang dibutuhkan untuk proses verifikasi kata sandi di masa depan (algoritma, cost factor, salt, dan ciphertext) telah terkemas rapi di dalam string 60 karakter ini.
Evolusi Prefix Identifier ($2a$, $2b$, $2y$, $2x$)
$2a$: Spesifikasi asli implementasi Bcrypt OpenBSD yang diterbitkan pada tahun 1999.$2y$: Standar resmi yang diperkenalkan pada PHP 5.3.7 untuk memperbaiki bug komparasi karakter 8-bit pada implementasi pustaka Crypt PHP tanpa merusak kompatibilitas hash yang ada.$2b$: Standar modern OpenBSD yang dirilis pada Februari 2014 untuk memperbaiki celah pembacaan panjang kata sandi (wrap-around bug) pada implementasi kernel OpenBSD asli.$2x$: Identifier historis PHP untuk menandai hash yang pernah dibuat dengan bug penanganan karakter UTF-8 lawas.
Tabel Benchmark Cost Factor (Work Factor Rounds)
Kekuatan utama Bcrypt terletak pada parameter Cost Factor (Work Factor) yang adaptif terhadap hukum Moore. Setiap penambahan nilai cost sebesar +1 akan menggandakan secara eksponensial (2x lipat) jumlah operasi komputasi dan durasi waktu yang dibutuhkan prosesor untuk memproses sebuah kata sandi.
| Cost Factor | Jumlah Iterasi ($2^{\text{cost}}$) | Estimasi Waktu CPU | Tingkat Keamanan | Rekomendasi Penggunaan |
|---|---|---|---|---|
| Cost 4 โ 7 | 16 โ 128 | < 5 ms | Rendah (Rawan Brute-Force) | Hanya untuk Automated Unit Testing / Seed Data |
| Cost 8 โ 9 | 256 โ 512 | ~ 20 โ 45 ms | Sedang | Perangkat IoT atau Server dengan CPU terbatas |
| Cost 10 (Default) | 1.024 | ~ 70 โ 100 ms | Tinggi (Sangat Aman) | Standar Aplikasi Web & REST API Production |
| Cost 12 (Optimal) | 4.096 | ~ 250 โ 350 ms | Sangat Tinggi (Enterprise) | Aplikasi Keuangan, FinTech, & Portal Sensitif |
| Cost 14 โ 15 | 16.384 โ 32.768 | > 1,5 โ 3,5 detik | Maksimal (Paranoid Mode) | Bisa menyebabkan Denial of Service (DoS) jika lonjakan login tinggi |
Perbandingan Kriptografi: Bcrypt vs Argon2id vs PBKDF2 vs Scrypt
Dalam lanskap keamanan siber modern, terdapat beberapa algoritma password hashing yang diakui oleh OWASP dan NIST. Memahami perbedaan mendasar tiap algoritma membantu Anda menentukan strategi arsitektur autentikasi yang tepat:
| Algoritma | Tipe Bottleneck | GPU/ASIC Resistance | Status Dukungan & Adopsi |
|---|---|---|---|
| Bcrypt (Blowfish) | CPU & Cache L1/L2 | Sangat Tinggi | Standar industri de-facto, didukung 100% native di seluruh bahasa pemrograman. |
| Argon2id | Memory-Hard & CPU Time | Maksimal (Kebal Side-Channel) | Pemenang Password Hashing Competition (PHC) 2015, standar baru OWASP. |
| PBKDF2 (HMAC-SHA256) | CPU Iterations Murni | Sedang (Rentan FPGA/ASIC) | Standar kepatuhan FIPS-140 & sertifikasi kepatuhan perbankan legacy. |
| Scrypt | RAM Memory-Hard | Tinggi | Populer pada implementasi cryptocurrency wallet (Litecoin, Ethereum keystore). |
Panduan Implementasi Kode Bcrypt di Berbagai Bahasa Pemrograman
Berikut adalah contoh implementasi kode produksi yang aman dan mengikuti standar terbaik untuk melakukan hashing serta verifikasi password di PHP, Node.js, Python, Golang, Java (Spring Security), dan C# (.NET):
<?php
// 1. Generate Bcrypt Hash dengan custom cost 12
$passwordPlain = 'P@ssw0rdRahasia2025!';
$hash = password_hash($passwordPlain, PASSWORD_BCRYPT, ['cost' => 12]);
echo "Bcrypt Hash: " . $hash . "\n";
// Output: $2y$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
// 2. Verifikasi Password Saat User Login
$inputUser = 'P@ssw0rdRahasia2025!';
if (password_verify($inputUser, $hash)) {
echo "Login Berhasil: Password Valid!\n";
// 3. Otomatis rehash jika standar cost sistem dinaikkan
if (password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 12])) {
$newHash = password_hash($inputUser, PASSWORD_BCRYPT, ['cost' => 12]);
// Simpan $newHash ke database pengguna
}
} else {
echo "Login Gagal: Password Salah!\n";
}
?> const bcrypt = require('bcryptjs');
async function handlePasswordSecurity() {
const plainPassword = 'P@ssw0rdRahasia2025!';
const saltRounds = 12;
// 1. Generate Hash Async (Non-blocking Event Loop)
const hashedPassword = await bcrypt.hash(plainPassword, saltRounds);
console.log('Generated Hash:', hashedPassword);
// 2. Verifikasi Password Saat Pengguna Login
const userInput = 'P@ssw0rdRahasia2025!';
const isMatch = await bcrypt.compare(userInput, hashedPassword);
if (isMatch) {
console.log('Autentikasi Sukses: Password Cocok');
} else {
console.log('Autentikasi Gagal: Password Tidak Cocok');
}
}
handlePasswordSecurity(); import bcrypt
# 1. Hashing Password dengan Cost Factor 12
password = "P@ssw0rdRahasia2025!".encode('utf-8')
salt = bcrypt.gensalt(rounds=12)
hashed_password = bcrypt.hashpw(password, salt)
print("Bcrypt Hash:", hashed_password.decode('utf-8'))
# 2. Verifikasi Password Saat Otentikasi
input_password = "P@ssw0rdRahasia2025!".encode('utf-8')
if bcrypt.checkpw(input_password, hashed_password):
print("Password Valid: Akses Diberikan")
else:
print("Password Tidak Valid: Akses Ditolak") package main
import (
"fmt"
"golang.org/x/crypto/bcrypt"
)
func main() {
password := []byte("P@ssw0rdRahasia2025!")
// 1. Generate Hash dengan Cost Factor 12
hashedPassword, err := bcrypt.GenerateFromPassword(password, 12)
if err != nil {
panic(err)
}
fmt.Println("Hash:", string(hashedPassword))
// 2. Verifikasi Password
err = bcrypt.CompareHashAndPassword(hashedPassword, []byte("P@ssw0rdRahasia2025!"))
if err == nil {
fmt.Println("Password Cocok!")
} else {
fmt.Println("Password Salah!")
}
} import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class PasswordSecurityService {
public static void main(String[] args) {
// Inisialisasi encoder dengan strength/cost factor 12
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(12);
String plainPassword = "P@ssw0rdRahasia2025!";
// 1. Generate Bcrypt Hash
String hashedPassword = passwordEncoder.encode(plainPassword);
System.out.println("Generated Bcrypt Hash: " + hashedPassword);
// 2. Verifikasi Password Saat Login
String userInputPassword = "P@ssw0rdRahasia2025!";
boolean isMatch = passwordEncoder.matches(userInputPassword, hashedPassword);
if (isMatch) {
System.out.println("Login Berhasil: Password Valid!");
} else {
System.out.println("Login Gagal: Password Salah!");
}
}
} using System;
using BCrypt.Net;
namespace AppSecurity
{
public class Program
{
public static void Main()
{
string rawPassword = "P@ssw0rdRahasia2025!";
int workFactor = 12;
// 1. Generate Bcrypt Hash dengan custom work factor 12
string passwordHash = BCrypt.Net.BCrypt.HashPassword(rawPassword, workFactor);
Console.WriteLine($"Hash: {passwordHash}");
// 2. Verifikasi Password Saat Pengguna Login
string loginInput = "P@ssw0rdRahasia2025!";
bool isValid = BCrypt.Net.BCrypt.Verify(loginInput, passwordHash);
if (isValid)
{
Console.WriteLine("Otentikasi Berhasil: Password Cocok");
}
else
{
Console.WriteLine("Otentikasi Gagal: Password Tidak Cocok");
}
}
}
} Batasan Kritis 72-Byte Algoritma Bcrypt & Cara Mengatasinya
Salah satu karakteristik arsitektur internal dari sandi blok Blowfish yang menjadi fondasi Bcrypt adalah adanya batasan panjang kata sandi maksimal 72 byte.
Batasan 72 byte pada Bcrypt dihitung berdasarkan ukuran memori byte biner, bukan jumlah karakter visual (string length):
- โKarakter ASCII Standar (A-Z, 0-9, simbol dasar): Memakan
1 byteper karakter (maksimal 72 karakter visual). - โAksara Multi-Byte (Arab, Sirilik, Devanagari, Yunani, Mandarin): Memakan
2 hingga 3 byteper karakter (batas tercapai di ~24โ36 karakter visual). - โEmoji & Simbol Khusus UTF-8 4-Byte (misal: ๐, ๐, ๐ป): Memakan
4 byteper karakter visual.
Strategi Solusi Terbaik: Pre-Hashing (Bcrypt + HMAC-SHA256)
Untuk aplikasi skala besar yang mengizinkan *passphrase* panjang (lebih dari 72 karakter) atau mendukung karakter multi-byte bebas tanpa risiko pemotongan, solusi yang direkomendasikan OWASP adalah menerapkan Pre-Hashing sebelum diteruskan ke fungsi Bcrypt:
- Input kata sandi pengguna di-hash terlebih dahulu menggunakan
HMAC-SHA256dengan Server Pepper rahasia yang disimpan di environment server terpisah. - Hasil digest SHA-256 yang selalu berukuran tetap 32 byte (atau 44 karakter Base64) kemudian di-hash menggunakan algoritma
Bcryptdengan cost factor 12.
$secureHash = password_hash(hash_hmac('sha256', $plainPassword, $serverPepperKey), PASSWORD_BCRYPT, ['cost' => 12]); 
Rusmawan Abdullah Sani
DevOps Engineer & Security Auditor at infokodingPraktisi keamanan siber dan backend architecture. Seluruh algoritma hashing pada alat ini dikonfigurasi mengikuti standar keamanan kriptografi modern (OWASP Password Storage Cheat Sheet & NIST Special Publication 800-63B).
FAQ: Tanya Jawab Seputar Algoritma Bcrypt & Password Security
Mengapa hash Bcrypt selalu menghasilkan output berbeda untuk password yang sama?
Karena algoritma Bcrypt secara otomatis menghasilkan 128-bit Salt unik dan acak setiap kali fungsi hash dipanggil. Fitur ini sengaja dibuat agar dua pengguna yang kebetulan memiliki kata sandi identik (misalnya password123) akan memiliki string hash yang sama sekali berbeda di database, sehingga kebal terhadap serangan kamus (Dictionary Attack) dan Rainbow Tables.
Berapa nilai Cost Factor yang paling direkomendasikan untuk web aplikasi saat ini?
Untuk server standar produksi saat ini, nilai Cost Factor 10 hingga 12 adalah pilihan paling ideal. Pada Cost 10, waktu komputasi berkisar antara 70โ100 milidetik per hash, yang sangat cepat bagi pengguna login sah, namun menjadi mimpi buruk yang mustahil ditembus bagi peretas yang ingin melakukan jutaan tebakan kata sandi.
Bisakah string hash Bcrypt di-decrypt (didekripsi) kembali menjadi teks aslinya?
Tidak bisa. Bcrypt adalah fungsi one-way cryptographic hash (satu arah), bukan algoritma enkripsi dua arah (seperti AES atau RSA). Tidak ada kunci dekripsi untuk mengembalikan hash ke teks semula. Satu-satunya cara memverifikasi adalah dengan meng-hash password input baru dan membandingkan hasil perhitungan ciphertext-nya.
Apakah data password yang dimasukkan ke tool ini disimpan atau dicatat di server InfoKoding?
100% Tidak Ada Data yang Dikirim. Seluruh komputasi hashing dan verifikasi dieksekusi secara lokal di dalam memori peramban (browser) Anda menggunakan pustaka bcrypt.js. Anda bahkan dapat mematikan koneksi internet (mode offline) saat menggunakan alat ini.
Apa perbedaan antara Bcrypt, Argon2, dan PBKDF2?
Bcrypt adalah standar industri yang teruji waktu sejak 1999 berbasis CPU cost. PBKDF2 adalah standar NIST klasik yang juga berbasis iterasi CPU. Sementara Argon2 (pemenang Password Hashing Competition 2015) adalah algoritma generasi terbaru yang mengkombinasikan parameter memori (*Memory-Hard Function*) dan CPU time untuk mencegah serangan ASIC/GPU tingkat lanjut.
Bagaimana cara migrasi dari hash MD5/SHA lama ke Bcrypt secara aman?
Lakukan teknik Lazy Rehash on Login. Saat pengguna login dengan password lamanya, verifikasi dulu hash MD5 lama. Jika valid, langsung konversi password plaintext menjadi hash Bcrypt baru dan simpan ke database, lalu hapus hash lama. Dalam beberapa minggu, mayoritas pengguna aktif akan otomatis bermigrasi ke Bcrypt.


