bcrypt untuk penghashan kata sandi Mengapa Enkripsi Sendiri Tidak Cukup
Jika Anda menyimpan kata sandi pengguna menggunakan AES, RSA, atau bahkan SHA-256, Anda melakukannya dengan salah. Bukan sedikit salah — salah secara mendasar. Ini adalah kesalahan keamanan paling umum dalam pengembangan web, dan memiliki solusi yang sederhana: gunakan fungsi penghashan kata sandi yang tepat seperti bcrypt.
Berikut alasannya, bagaimana bcrypt bekerja, dan bagaimana kode siap produksi terlihat.
Mengapa Kata Sandi Perlu Perlakuan Khusus
Operasi kriptografi kebanyakan dirancang untuk dapat dibalik atau cepat. Enkripsi dirancang untuk dapat dibalik — itu seluruh tujuannya. SHA-256 dan MD5 sangat cepat, memproses ratusan gigabyte per detik. Kedua sifat ini sangat berbahaya bagi kata sandi.
Ketika penyerang mendapatkan database Anda, mereka mendapatkan hash kata sandi Anda. Dengan enkripsi, jika mereka menemukan kunci, mereka dapat mendekripsi semua data. Dengan hash cepat seperti MD5 atau SHA-256, mereka menjalankan serangan brute-force yang diakselerasikan oleh GPU — perangkat modern dapat menguji ratusan miliar hash MD5 per detik. Kata sandi Anda yang “kompleks” dapat ditebak dalam beberapa menit.
Kata sandi perlu:
- Tidak dapat dibalik — bahkan dengan kunci atau algoritma, Anda tidak bisa mendapatkan teks aslinya kembali
- Lambat dalam perhitungan — ketidakcepatan yang disengaja membuat serangan brute-force tidak praktis
- Unik per pengguna — kata sandi yang sama harus menghasilkan hash yang berbeda
bcrypt memenuhi ketiga syarat ini. Fungsi hash umum dan enkripsi tidak.
Penghashan vs Enkripsi vs Penghashan Kata Sandi
Ini tidak dapat diganti satu sama lain:
| Pendekatan | Dapat dibalik? | Cepat? | Aman untuk Kata Sandi? |
|---|---|---|---|
| Enkripsi (AES, RSA) | Ya — dengan kunci | Ya | TIDAK |
| Penghashan cepat (MD5, SHA-256) | TIDAK | Ya (secara desain) | TIDAK |
| Penghashan kata sandi (bcrypt, Argon2id) | TIDAK | Tidak (secara desain) | Ya |
Kebalikan enkripsi merupakan penentu utama: jika kunci terkompromi, maka semua kata sandi juga terkompromi. Penghashan cepat juga merupakan penentu utama: kecepatan memungkinkan serangan brute-force. Fungsi penghashan kata sandi dirancang untuk lambat — dan itu adalah intinya.
Bagaimana bcrypt Bekerja
bcrypt, dirancang pada tahun 1999 oleh Niels Provos dan David Mazières, melakukan tiga hal yang penting:
1. Penambahan garam (salting). Sebelum menghash, bcrypt menghasilkan garam acak (16 byte) dan mencakupnya dalam output hash. Bahkan jika dua pengguna memiliki kata sandi yang sama, hash mereka berbeda. Ini sepenuhnya menghentikan serangan rainbow table yang pra-komputasi.
2. Faktor kerja (cost). bcrypt menerima parameter biaya (biasanya 10–14). Setiap peningkatan memperdublikasikan waktu perhitungan. Pada biaya 12, proses hashing membutuhkan waktu sekitar 250–400ms pada perangkat modern. Ini sangat lambat untuk permintaan login — tetapi mengubah serangan brute-force miliar menjadi operasi yang memakan waktu bertahun-tahun.
3. Outputnya bersifat terintegrasi. Hash bcrypt terlihat seperti $2b$12$... dan mengandung versi algoritma, faktor biaya, garam, dan hash secara bersamaan. Anda tidak perlu kolom garam terpisah. Simpan seluruh string tersebut.
Kode Produksi: Node.js dan Python
Node.js (bcryptjs atau bcrypt)
const bcrypt = require('bcrypt');
const SALT_ROUNDS = 12;
// Hash a password
async function hashPassword(plaintext) {
return bcrypt.hash(plaintext, SALT_ROUNDS);
}
// Verify a password against a stored hash
async function verifyPassword(plaintext, storedHash) {
return bcrypt.compare(plaintext, storedHash);
}
// Usage
const hash = await hashPassword('hunter2');
// Store `hash` in your database
const isValid = await verifyPassword('hunter2', hash);
// true
Python (bcrypt)
import bcrypt
COST = 12
def hash_password(plaintext: str) -> bytes:
salt = bcrypt.gensalt(rounds=COST)
return bcrypt.hashpw(plaintext.encode('utf-8'), salt)
def verify_password(plaintext: str, stored_hash: bytes) -> bool:
return bcrypt.checkpw(plaintext.encode('utf-8'), stored_hash)
# Usage
hashed = hash_password('hunter2')
# Store hashed in your database
is_valid = verify_password('hunter2', hashed)
# True
Simpan string hash lengkap. Jangan simpan teks murni, jangan simpan garam secara terpisah, jangan simpan nilai tengah.
Memilih Faktor Kerja
Faktor biaya yang tepat tergantung pada perangkat Anda. Tujuannya: membuat setiap operasi hashing membutuhkan 200–500ms pada server produksi Anda. Ini cukup cepat untuk pengalaman pengguna yang baik, tetapi lambat cukup untuk mengganggu penyerang.
Rekomendasi saat ini: biaya 12 sebagai minimum, 14 untuk akun berharga tinggi (admin, keuangan). Jalankan uji coba pada perangkat Anda secara aktual:
// Node.js: benchmark different cost factors
const bcrypt = require('bcrypt');
for (let cost = 10; cost <= 14; cost++) {
const start = Date.now();
await bcrypt.hash('benchmark', cost);
console.log(`Cost ${cost}: ${Date.now() - start}ms`);
}
Jika biaya 12 membutuhkan kurang dari 100ms, tingkatkan. Jika biaya 14 membutuhkan lebih dari 1000ms, turunkan ke 13. Ulangi setiap tahun — perangkat semakin cepat, dan faktor biaya Anda harus tetap berjalan.
Anda dapat menguji penghashan bcrypt secara interaktif dengan IO Tools Generator Hash bcrypt.
bcrypt vs Argon2id vs scrypt
bcrypt telah diuji dan sangat didukung. Namun, memiliki kelemahan: tidak membutuhkan memori. Seorang penyerang dengan perangkat khusus (ASIC atau FPGA) dapat mempercepat serangan secara lebih efisien dibandingkan dengan alternatif yang membutuhkan memori.
| Algoritma | Memori-Hard | Tahan terhadap Paralelisme | Rekomendasi |
|---|---|---|---|
| bcrypt | TIDAK | Sebagian | Cukup baik sebagai default; gunakan biaya ≥12 |
| scrypt | Ya | Sebagian | Lebih baik daripada bcrypt, dengan alat yang lebih sedikit |
| Argon2id | Ya | Ya | Disarankan untuk proyek baru |
Untuk proyek baru: gunakan Argon2id. Ia menang dalam Kompetisi Penghashan Kata Sandi (2015), membutuhkan memori, tahan terhadap serangan GPU dan ASIC, dan sekarang merupakan rekomendasi teratas dari OWASP. API-nya hampir identik dengan bcrypt.
Untuk proyek yang sudah ada: jika Anda sudah menggunakan bcrypt dengan faktor biaya yang wajar, migrasi tidak mendesak. Tambahkan ke refaktor besar berikutnya.
Kesalahan Umum dalam Implementasi
Menghash hash. Beberapa pengembang menghash kata sandi di sisi klien sebelum dikirim, lalu menghash kembali di sisi server. Hash di sisi klien menjadi “kata sandi.” Anda sekarang menghash string heksadesimal berukuran tetap, bukan kata sandi yang dipilih oleh manusia — Anda kehilangan sesuatu dari penghashan ganda, tetapi Anda juga tidak mendapatkan manfaat, dan Anda memperkenalkan kebingungan.
Masalah pemotongan 72 byte. bcrypt secara diam-diam mengabaikan semua yang melebihi 72 byte. Kata sandi 100 karakter dan kata sandi 72 karakter yang memiliki 72 karakter pertama yang sama dianggap sama oleh bcrypt. Jika pengguna Anda mengatur kata sandi yang sangat panjang, ini merupakan degradasi keamanan yang diam-diam. Solusi: hash terlebih dahulu dengan SHA-256 sebelum dikirim ke bcrypt — tetapi hanya jika Anda sepenuhnya memahami implikasinya, dan dokumentasikan secara jelas.
Faktor kerja yang lemah. Biaya 10 masih wajar pada tahun 2011. Pada tahun 2026, gunakan setidaknya 12. Jika catatan Anda saat ini menggunakan biaya 10, Anda dapat mengupgrade secara transparan: setelah login berhasil, re-hash kata sandi yang telah diverifikasi dengan biaya baru dan simpan hash yang diperbarui.
Ketergantungan asinkron. bcrypt sangat membutuhkan CPU. Gunakan selalu API asinkron (seperti yang ditunjukkan di atas) di Node.js untuk menghindari memblokir loop peristiwa. Penggunaan bcrypt sinkron di server Node akan membuat setiap permintaan lain menunggu.
Migrasi dari MD5/SHA ke bcrypt
Anda tidak dapat meng-hash ulang tanpa teks murni asli. Namun, Anda dapat melakukan migrasi secara oportunis:
- Tambahkan sebuah
password_hashkolom di samping kolom lamapassword_md5kolom - Pada saat login berhasil (ketika Anda memiliki teks murni), hash dengan bcrypt dan simpan di
password_hash, hapus kolom lama - Setelah periode migrasi, pengguna yang belum pernah login dapat dipaksa untuk mengatur ulang kata sandi mereka
- Sekali
password_md5adalah kosong untuk semua pengguna, hapus kolom tersebut
Ini adalah pendekatan standar dan tidak membutuhkan downtime.
Intinya
Enkripsi digunakan untuk data yang perlu diambil kembali. Penghashan digunakan untuk data yang perlu diverifikasi. Kata sandi harus diverifikasi, bukan diambil kembali — yang berarti enkripsi adalah alat yang salah.
bcrypt memberikan salting, kecepatan yang dapat dikonfigurasi, dan format hash yang terintegrasi. Ini telah menjadi jawaban yang tepat selama 25 tahun. Gunakan dengan biaya 12 atau lebih, gunakan Argon2id untuk proyek baru, dan segera migrasi dari MD5 dan SHA-256.
Mengabaikan ini bukan risiko hipotetis. Database dapat dibobol. Saat itu terjadi, kata sandi yang di-hash dengan bcrypt secara komputasi tidak dapat ditebak. Hash MD5 dapat ditebak dalam satu malam.
Anda mungkin juga menyukai
Instal Ekstensi Kami
Tambahkan alat IO ke browser favorit Anda untuk akses instan dan pencarian lebih cepat
恵 Papan Skor Telah Tiba!
Papan Skor adalah cara yang menyenangkan untuk melacak permainan Anda, semua data disimpan di browser Anda. Lebih banyak fitur akan segera hadir!
Alat Wajib Coba
Lihat semua Pendatang baru
Lihat semuaMemperbarui: Kita alat terbaru ditambahkan pada 26 Apr 2026
