Hari ini saya mulai episode tentang hal yang paling sering saya salah paham sebagai programmer: cara menyimpan password pengguna. Di episode #2 kita sudah lihat bagaimana kebocoran data jadi awal mula banyak insiden besar — dan kebocoran yang paling menyakitkan biasanya adalah kebocoran berisi password. Selama ini kebiasaan saya sederhana saja — simpan di database pakai hash bawaan framework, selesai. Ternyata di balik “sudah pakai hash” itu ada banyak sekali keputusan yang menentukan apakah data pengguna aman atau tidak.
Plaintext: kenapa ini dosa besar
Bayangkan kita menyimpan password pengguna persis seperti yang mereka ketik: r4h4s14-2026. Ini namanya plaintext. Kalau sekali saja database kita bocor — SQL injection, backup yang tertinggal di server publik, atau laptop admin dicuri — SEMUA password pengguna langsung jatuh ke tangan orang lain. Dan kebanyakan orang memakai password yang sama di banyak layanan, jadi satu bocor berarti puluhan akun ikut terancam. Prinsip yang saya catat di sini: database yang aman sekalipun tidak boleh berisi password dalam bentuk yang bisa langsung dipakai.
Hash: sidik jari digital, bukan salinan
Solusi dasarnya adalah hashing. Kalau hash itu sidik jari digital — input yang sama selalu menghasilkan sidik jari yang sama, tapi dari sidik jari kita TIDAK bisa merekonstruksi wajah aslinya. Password r4h4s14-2026 di-hash jadi string acak seperti $2y$10$..., dan yang disimpan di database hanya sidik jari itu. Saat pengguna login, kita hash password yang dikirimkan, lalu bandingkan hasilnya dengan yang tersimpan. Password aslinya tidak pernah kita tahu lagi — bahkan sebagai developer.
Tapi di sinilah kesalahan klasik programmer: memakai hash “biasa” seperti MD5 atau SHA-1. Dua hash ini dirancang CEPAT — itu memang gunanya untuk verifikasi file, bukan untuk password. Kecepatan itu jadi bumerang: attacker bisa menebak jutaan kandidat password per detik dengan GPU. Belum lagi ada yang namanya rainbow table — daftar prahitung hash dari password-password umum. Kalau dua pengguna punya password sama, hash-nya juga sama, dan attacker tinggal cocok-cocokkan.
Salt: sidik jari yang sengaja dibuat berbeda
Obatnya adalah salt — string acak yang ditambahkan ke password SEBELUM di-hash, satu salt unik per pengguna. Analoginya: setiap orang diberi sidik jari dalam tinta warna berbeda, jadi tabel cocok-cocokkan tidak ada gunanya. Dua orang dengan password sama akan menghasilkan hash yang sama sekali berbeda karena salt-nya beda. Salt disimpan bersama hash (memang tidak perlu rahasia), yang penting dia unik dan acak. Framework modern seperti Laravel sudah melakukan ini otomatis — kalau kita pakai Hash::make(), salt sudah tertanam di dalam string hash.
bcrypt & Argon2: hash yang sengaja dibuat lambat
Perbedaan mendasar antara hash untuk file dan hash untuk password: untuk password kita justru MAU lambat. bcrypt dan Argon2 punya parameter “cost” yang membuat proses hashing memakan waktu ratusan milidetik — tidak terasa oleh pengguna, tapi menghancurkan attacker yang mencoba menebak jutaan password per detik. Ini seperti memasang brankas di depan pintu: bukan untuk menghambat pemilik rumah, tapi untuk membuat perampok menyerah. Praktik yang saya catat untuk proyek Laravel: ikuti default framework (bcrypt cost 10, atau Argon2 kalau tersedia), jangan menurunkan cost demi kecepatan login.
MFA & passkey: lapisan kedua yang menyelamatkan
Hash yang bagus pun masih punya kelemahan: kalau pengguna memilih password lemah, semua teknik di atas tidak banyak menolong. Multi-Factor Authentication (MFA) menambah lapisan kedua — sesuatu yang pengguna TAHU (password), sesuatu yang pengguna PUNYA (OTP di aplikasi authenticator), atau sesuatu yang pengguna ADALAH (sidik jari). Passkey adalah evolusi terbaru: kredensial berbasis kriptografi asimetris yang tersimpan di perangkat, tidak bisa phished karena tidak pernah dikirimkan ke server manapun. Sebagai developer, saya mulai melihat passkey bukan lagi fitur “keren nanti”, tapi opsi login yang layak ditawarkan sekarang.
Pelajaran besar dari episode ini: menyimpan password bukan sekadar “pakai hash dan selesai”. Ada keputusan soal algoritma, salt, cost, dan lapisan autentikasi tambahan — dan setiap keputusan itu menentukan apakah kita sedang melindungi pengguna atau hanya merasa aman tanpa alasan.
Komentar Terbaru