Jangan pernah menyimpan password dalam bentuk plain text. Jika database bocor, semua password pengguna terekspos. Solusinya: hashing.
Hashing vs Encryption:
| Aspek | Hashing | Encryption |
|---|---|---|
| Arah | Satu arah (irreversible) | Dua arah (bisa decrypt) |
| Output | Selalu panjang tetap | Panjang bervariasi |
| Tujuan | Verifikasi integritas | Menyembunyikan data |
| Contoh | bcrypt, argon2 | AES, RSA |
Mengapa hashing biasa tidak cukup:
// MD5/SHA — JANGAN dipakai untuk password!
hash("password123") → "ef92b778bafe771e89245b89ecbc08a44a4e166c06659911881f383d4473e94f"
// Masalah: hash yang sama untuk input yang sama → rentan rainbow table attack
Salt — bumbu rahasia: Salt adalah string random yang ditambahkan ke password sebelum hashing. Ini membuat hash unik meskipun passwordnya sama.
"password123" + salt "x7k9" → hash "a1b2c3..."
"password123" + salt "m3n4" → hash "d4e5f6..." (berbeda!)
Algoritma yang direkomendasikan:
- bcrypt — standar industri, otomatis salt, configurable cost factor
- Argon2 — pemenang Password Hashing Competition 2015, memory-hard
- scrypt — memory-hard, dipakai cryptocurrency
Implementasi dengan bcrypt:
const bcrypt = require("bcrypt");
// Membuat hash (saat registrasi):
const saltRounds = 12; // cost factor — makin tinggi makin lambat (aman)
const hash = await bcrypt.hash("password123", saltRounds);
// "$2b$12$LJ3m4ks8Hj7vG..." — salt sudah termasuk di dalamnya
// Memverifikasi (saat login):
const isMatch = await bcrypt.compare("password123", hash);
console.log(isMatch); // true
// Password salah:
const wrong = await bcrypt.compare("wrongpass", hash);
console.log(wrong); // false
Cost factor (work factor): Angka ini menentukan berapa kali hashing diulang. Setiap kenaikan 1 = waktu 2x lipat:
- Cost 10 → ~100ms
- Cost 12 → ~400ms (recommended)
- Cost 14 → ~1.6s
Tujuannya: membuat brute force attack sangat lambat. Penyerang yang harus mencoba 1 miliar password akan butuh ribuan tahun.
Jangan lakukan ini:
- Menyimpan password plain text
- Menggunakan MD5/SHA untuk password (terlalu cepat, rentan brute force)
- Membuat algoritma hashing sendiri
- Menggunakan salt yang sama untuk semua user
- Mengirim password via URL query parameter
Best practices:
- Gunakan bcrypt atau Argon2 — mereka menangani salt secara otomatis
- Set cost factor yang membuat hashing butuh minimal 200-400ms
- Naikkan cost factor seiring waktu (hardware makin cepat)
- Implementasikan rate limiting untuk mencegah brute force
- Pertimbangkan pepper — secret key tambahan yang disimpan di server (bukan di database)