Kenapa Tidak Boleh Simpan Password Plain Text?
Jika database bocor dan password disimpan dalam plain text, semua akun pengguna langsung terekspos. Banyak pengguna menggunakan password yang sama di berbagai layanan, sehingga dampaknya bisa meluas.
Evolusi Penyimpanan Password
- Plain text — Paling buruk, langsung terekspos saat breach
- Encrypted — Bisa didekripsi jika key bocor
- MD5/SHA hash — Rentan terhadap rainbow table dan brute force
- Salted hash — Menambahkan random string sebelum hashing
- Bcrypt/Argon2 — Algoritma yang dirancang khusus untuk password hashing
Bcrypt: Standar Industri
Bcrypt dirancang khusus untuk password hashing dengan fitur:
- Salt otomatis — Setiap hash punya salt unik
- Cost factor — Bisa diperlambat seiring hardware makin cepat
- Tahan brute force — Intentionally lambat untuk mencegah serangan
// Node.js dengan bcrypt
const bcrypt = require("bcrypt");
const saltRounds = 12;
// Membuat hash
const hashedPassword = await bcrypt.hash("passwordUser", saltRounds);
// Hasil: $2b$12$LJ3m4yPO0eDKwRGBMlKP8e...
// Verifikasi
const isValid = await bcrypt.compare("passwordUser", hashedPassword);
// true jika cocok
PHP Password Hashing
// PHP menggunakan password_hash (menggunakan bcrypt secara default)
$hash = password_hash("passwordUser", PASSWORD_DEFAULT);
// Verifikasi
if (password_verify("passwordUser", $hash)) {
echo "Password benar!";
}
// Cek apakah hash perlu di-rehash (cost factor berubah)
if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
$newHash = password_hash("passwordUser", PASSWORD_DEFAULT);
// Update hash di database
}
Argon2: Generasi Berikutnya
Argon2 adalah pemenang Password Hashing Competition (2015) dan menjadi rekomendasi terbaru:
- Argon2id — Kombinasi Argon2i dan Argon2d, direkomendasikan untuk password
- Bisa dikonfigurasi: memory cost, time cost, dan parallelism
- Lebih tahan terhadap GPU dan ASIC attacks dibanding bcrypt
Best Practices
- Gunakan bcrypt atau Argon2id — jangan gunakan MD5, SHA-1, atau SHA-256 untuk password
- Set cost factor yang membuat hashing memakan waktu ~250ms
- Jangan batasi panjang password secara ketat (minimal 8 karakter, maksimal 128)
- Implementasikan password strength checker di frontend