Kebocoran database sudah menjadi risiko standar bagi setiap aplikasi yang menyimpan kredensial pengguna. Ketika tabel users aplikasi kamu jatuh ke tangan penyerang—melalui celah SQL Injection, file backup yang bocor, atau peretasan infrastruktur server—satu hal menentukan seberapa parah dampak insiden tersebut: bagaimana password pengguna disimpan.
Jika password tersimpan sebagai plaintext, penyerang segera miliki semua akun. Kondisi ini menjadi lebih parah karena banyak pengguna menggunakan password yang sama di berbagai layanan, sehingga kebocoran di aplikasi kamu bisa merusak akun email, media sosial, hingga rekening bank mereka di tempat lain.
Berbeda halnya jika password disimpan sebagai hash yang dibuat dengan algoritma modern. Penyerang hanya mendapatkan rentetan karakter acak yang tidak dapat dikembalikan ke password aslinya. Tim pengembang mendapat waktu untuk memaksa reset password, menutup celah, dan membatasi kerusakan sebelum situasi memburuk.
Artikel ini adalah panduan praktis untuk developer PHP dan Laravel yang ingin menerapkan standar industri modern dalam penyimpanan password. Kamu akan mempelajari mengapa hashing satu arah wajib digunakan, kapan memilih bcrypt atau Argon2id, cara menggunakan password_hash() di PHP native beserta Facade Hash di Laravel, tuning cost factor, peran salt dan pepper, rehash-on-login, migrasi dari algoritma lama seperti MD5 dan SHA-1, serta rate limiting pada endpoint login.
Panduan ini tidak membahas alur login lengkap dari awal sampai akhir. Untuk membahas autentikasi secara menyeluruh, kamu bisa membaca artikel authentication. Di sini, kami fokus pada bagian kunci: cara menyimpan dan memverifikasi password dengan aman.
Hashing Satu Arah vs Enkripsi Dua Arah
Kesalahan awal yang sering dilakukan developer pemula adalah menyimpan password dengan enkripsi dua arah seperti AES atau RSA. Enkripsi reversible: data asli diubah menjadi ciphertext dengan kunci, lalu dapat dikembalikan ke bentuk asli dengan kunci yang sama atau pasangan. Enkripsi cocok untuk data yang harus dibaca kembali sistem di kemudian hari, seperti token API pihak ketiga, nomor kartu kredit, atau data identitas pribadi.
Enkripsi adalah pilihan yang salah untuk password. Alasannya sederhana: jika aplikasi bisa mendekode ciphertext menjadi password asli, maka penyerang yang mendapat kunci enkripsi—dari file .env, konfigurasi server, atau source code—bisa melakukan hal yang sama. Dalam skenario kebocoran data, enkripsi dua arah pada password pada dasarnya hanya menunda waktu sampai kunci ditemukan.
Hashing adalah fungsi satu arah yang irreversibel. Hashing menerima input berukuran berapa pun dan menghasilkan output string berukuran tetap yang disebut digest atau hash. Tidak ada rumus atau kunci yang bisa mengubah hash kembali menjadi password aslinya.
Mekanisme login dengan hashing bekerja tanpa pernah menyimpan password asli:
- Saat pendaftaran, aplikasi menghitung hash dari password dan menyimpannya di database.
- Saat login, aplikasi menghitung hash dari password yang dimasukkan pengguna.
- Aplikasi membandingkan hash baru dengan hash yang tersimpan. Jika cocok, password yang dimasukkan identik dengan password saat pendaftaran.
Sistem tidak perlu mengetahui password asli pengguna untuk memverifikasi identitas mereka.
Mengapa MD5 dan SHA-1 Berbahaya untuk Password
MD5 dan SHA-1 didesain sebagai fast hash algorithm. Tujuan awalnya adalah menghitung checksum integritas file berukuran besar secepat mungkin. Kecepatan tinggi ini justru menjadi celah fatal ketika diterapkan pada password. GPU modern mampu menghitung miliaran hash MD5 atau SHA-1 setiap detik, sehingga serangan brute-force atau dictionary attack terhadap password yang di-hash MD5 sangat efektif. Sebaliknya, algoritma password modern seperti bcrypt dan Argon2id sengaja dibuat lambat sehingga mencoba ribuan kombinasi memakan waktu yang jauh lebih lama.
Masalah lain adalah rainbow tables. Karena MD5 bersifat deterministik (input yang sama selalu menghasilkan hash yang sama), penyerang telah membuat tabel raksasa berisi miliaran kombinasi password populer beserta hash MD5-nya. Jika database yang berisi hash MD5 tercuri, penyerang cukup mencocokkan hash dengan indeks tabel untuk mengetahui password asli secara instan tanpa komputasi tambahan.
MD5 dan SHA-1 juga rentan terhadap collision attack, di mana dua string input yang berbeda menghasilkan hash yang sama. Hal ini berpotensi membuat password yang salah lolos verifikasi login.
SHA-256 dan fungsi hash cepat lainnya memiliki masalah yang sama. Kecepatan yang baik untuk integritas data justru menjadi kelemahan untuk penyimpanan kredensial. Untuk password, kamu perlu algoritma yang sengaja dibuat lambat, seperti bcrypt dan Argon2id.
Komponen Penting: Salt, Pepper, dan Cost Factor
Salt
Salt adalah string acak unik per pengguna yang digabungkan dengan password sebelum di-hash. Tanpa salt, lima puluh pengguna yang memilih password "password123" akan memiliki nilai hash yang sama di database. Dengan salt, setiap pengguna menghasilkan hash yang berbeda meski passwordnya identik.
Keuntungan utama salt adalah mencegah rainbow table dan menghindari deteksi hash yang cocok antara dua pengguna. password_hash() dan Hash::make() secara otomatis menghasilkan salt dengan CSPRNG dan menyematkannya di dalam string hash output. Kamu tidak perlu membuat salt sendiri, tidak perlu menyimpannya di kolom terpisah, dan opsi salt diabaikan sejak PHP 8.0. Biarkan runtime yang menangani salt.
Pepper
Pepper sering dibingungkan dengan salt, namun keduanya berbeda. Pepper adalah nilai rahasia global tingkat aplikasi atau server, disimpan di luar database—misalnya di .env, environment variable, KMS, atau HSM. Pepper digabungkan dengan password sebelum di-hash sebagai defense-in-depth.
Jika database bocor akibat SQL Injection atau kebocoran backup, penyerang hanya mendapatkan hash. Tanpa nilai pepper yang tersimpan terpisah di server, penyerang kesulitan menjalankan cracking offline meski memiliki akses penuh ke database.
Sedikit catatan: pemasangan pepper menambah kompleksitas, terutama saat rotasi. Ganti pepper berarti semua hash lama tidak valid lagi dan biasanya memaksa reset password untuk semua pengguna. Pertimbangkan apakah manfaat defense-in-depth sebanding dengan kompleksitas tambahan bagi tim kamu.
Cost Factor dan Work Factor
Berbeda dengan MD5 yang sengaja dibuat cepat, algoritma password hashing modern memiliki parameter bernama cost factor atau work factor. Parameter ini menentukan seberapa besar daya komputasi yang dibutuhkan untuk menghasilkan satu hash.
Pada bcrypt, cost factor bersifat eksponensial. Setiap kenaikan nilai cost sebesar +1 menggandakan waktu perhitungan (2^cost iterasi). Cost 10 artinya 1.024 perulangan, cost 11 artinya 2.048, dan cost 12 artinya 4.096. Semakin tinggi cost, semakin lama waktu yang dibutuhkan penyerang untuk mencoba ribuan kombinasi password jika database bocor.
Tidak boleh terlalu rendah dan tidak boleh terlalu tinggi. Cost terlalu rendah membuat hash mudah dicrack oleh hardware modern. Cost terlalu tinggi membuat proses login terasa lambat dan membuka risiko denial of service: penyerang bisa mengirimkan ratusan request login palsu sekaligus untuk menghabiskan CPU server.
Target yang baik adalah eksekusi satu hash sekitar 250 hingga 500 milidetik di server produksi. Kamu bisa menyesuaikan cost berdasarkan benchmark pada hardware yang benar-benar kamu gunakan.
bcrypt vs Argon2id: Pilih Algoritma yang Tepat
bcrypt
bcrypt didasarkan pada cipher Blowfish. Output selalu dimulai dengan $2y$ dan panjangnya 60 karakter. Rentang cost valid adalah 4 hingga 31. Default cost PHP adalah 10 sebelum PHP 8.4, dan 12 sejak PHP 8.4. Laravel menggunakan default rounds sebesar 12.
bcrypt merupakan pilihan andal yang telah teruji waktu, namun tidak memiliki memory hardness. Seiring perkembangan GPU dan ASIC, perhitungan bcrypt dapat dipercepat oleh perangkat keras khusus. Selain itu, bcrypt hanya memproses 72 byte pertama dari password; karakter selanjutnya diabaikan. Kamu akan membahas batasan ini lebih lanjut di bagian berikutnya.
Argon2id
Argon2id adalah pemenang Password Hashing Competition 2015 dan ditetapkan dalam RFC 9106. Algoritma ini adalah memory-hard: selain membutuhkan waktu kalkulasi CPU, Argon2id mewajibkan alokasi RAM yang signifikan saat membuat hash. Hal ini membuat serangan paralel massal menggunakan GPU atau ASIC menjadi mahal dan tidak efisien.
Argon2id tersedia sejak PHP 7.3, asalkan build PHP kamu dikompilasi dengan dukungan Argon2 (libsodium). Parameter utamanya adalah memory_cost (KiB), time_cost (iterasi), dan threads (lane). OWASP merekomendasikan minimum m=19456 (sekitar 19 MiB), t=2, dan p=1. Laravel secara default menggunakan argon memory 65536, threads 1, dan time 4.
Untuk sistem baru, Argon2id adalah pilihan prioritas. bcrypt dengan cost 12 tetap merupakan alternatif andal jika Argon2id tidak tersedia di server kamu.
Argon2i, PBKDF2, dan scrypt
Argon2i tersedia sejak PHP 7.2 dan tahan side-channel attack, namun kurang tahan terhadap GPU dibanding Argon2id. OWASP tidak merekomendasikan Argon2i untuk penyimpanan password, jadi pilih Argon2id jika kamu akan menggunakan Argon2.
PBKDF2 cocok untuk kompatibilitas FIPS-140 dengan minimal 600.000 iterasi menggunakan HMAC-SHA-256. scrypt adalah alternatif memory-hard jika Argon2id tidak tersedia. Keduanya bukan pilihan pertama untuk password hashing di ekosistem PHP modern.
Batasan 72 Byte pada bcrypt dan Panjang Password
bcrypt hanya memproses 72 byte pertama dari password. Karakter selanjutnya diabaikan, sehingga password sangat panjang kehilangan entropi. Karakter multibyte dalam UTF-8 dapat menempati lebih dari satu byte, sehingga entropi hilang lebih cepat dari yang kamu kira.
Ada dua cara mengatasi hal ini. Pertama, batasi panjang password pada aplikasi sebelum hash dibuat—misalnya 64 hingga 128 karakter, atau batasi maksimal 72 byte. Kedua, gunakan Argon2id yang tidak memiliki batasan 72 byte ini.
Jangan mencoba mengatasi batasan 72 byte dengan pre-hashing password menggunakan SHA-256 lalu di-hash dengan bcrypt tanpa memahami risikonya. Pendekatan ini dapat memperkenalkan masalah seperti password shucking dan null byte. Jika kamu tidak yakin, biarkan password langsung di-hash dengan algoritma yang sesuai atau batasi panjang input di sisi aplikasi.
Implementasi Praktis di PHP Native
PHP menyediakan fungsi bawaan untuk password hashing sejak PHP 5.5. Kamu tidak perlu menulis algoritma sendiri atau menginstal library eksternal untuk tugas dasar ini.
Membuat Hash dengan password_hash()
Fungsi password_hash() menangani pembuatan salt acak, penerapan algoritma, dan penyusunan format hash akhir secara otomatis. Berikut contoh pembuatan hash bcrypt dengan cost 12 saat pendaftaran pengguna:
<?php
$plainPassword = $_POST['password'];
$options = [
'cost' => 12,
];
$hashedPassword = password_hash($plainPassword, PASSWORD_BCRYPT, $options);
// Simpan $hashedPassword ke kolom `password` (minimal 255 karakter)
String output bcrypt sudah mengandung algoritma, cost factor, salt, dan digest dalam satu nilai. Kamu tidak perlu mengekstrak salt secara manual saat verifikasi nanti.
Jika server kamu mendukung Argon2 (PHP 7.3+), kamu bisa menggunakan PASSWORD_ARGON2ID:
<?php
$plainPassword = $_POST['password'];
$argonOptions = [
'memory_cost' => 19456, // sekitar 19 MiB
'time_cost' => 2,
'threads' => 1,
];
$hashedPassword = password_hash($plainPassword, PASSWORD_ARGON2ID, $argonOptions);
Perilaku saat gagal: sejak PHP 8.0, password_hash() melempar ValueError jika gagal. Sebelum PHP 8.0, fungsi ini mengembalikan false.
Memverifikasi Password dengan password_verify()
Saat pengguna login, jangan pernah membandingkan string hash dengan operator == atau ===. Perbandingan string standar rentan terhadap timing attack, di mana penyerang mengukur perbedaan waktu eksekusi server untuk menebak karakter demi karakter hash.
Gunakan password_verify() yang dirancang tahan terhadap timing attack dengan perbandingan konstan waktu:
<?php
$userInputPassword = $_POST['password'];
$storedHashFromDb = $user->password; // diambil dari database
if (password_verify($userInputPassword, $storedHashFromDb)) {
// Password benar, lanjutkan proses login
} else {
// Password salah
}
password_verify() secara otomatis membaca header string hash untuk mengetahui algoritma, cost factor, dan posisi salt yang digunakan. Kamu tidak perlu mengetahui detailnya secara manual.
Upgrade Hash dengan password_needs_rehash()
Seiring waktu, standar keamanan berubah. Cost factor 10 yang dianggap aman beberapa tahun lalu mungkin terlalu cepat untuk standar saat ini. Kamu tidak ingin memaksa semua pengguna mengganti password sekaligus hanya untuk mengupgrade hash.
Solusinya adalah rehash-on-login dengan password_needs_rehash():
<?php
$userInputPassword = $_POST['password'];
$storedHashFromDb = $user->password;
$targetOptions = ['cost' => 12];
if (password_verify($userInputPassword, $storedHashFromDb)) {
if (password_needs_rehash($storedHashFromDb, PASSWORD_DEFAULT, $targetOptions)) {
$newHash = password_hash($userInputPassword, PASSWORD_DEFAULT, $targetOptions);
// Simpan $newHash ke database untuk mengganti hash lama
$stmt = $db->prepare("UPDATE users SET password = ? WHERE id = ?");
$stmt->execute([$newHash, $user->id]);
}
// Lanjutkan membuat session atau token login
}
Fungsi ini memeriksa apakah hash di database masih menggunakan algoritma atau cost yang lama. Jika iya, hash baru dibuat menggunakan password asli dari input login dan disimpan ke database. Pengguna yang tidak aktif akan mendapat hash baru secara bertahap setiap kali login berikutnya.
Fungsi pendukung lain yang berguna adalah password_get_info() untuk mengetahui algoritma dan opsi dari sebuah hash, serta password_algos() untuk daftar algoritma yang didukung oleh build PHP kamu.
Implementasi Praktis di Laravel
Laravel menyederhanakan password hashing melalui Facade Illuminate\Support\Facades\Hash. Secara default, Laravel menggunakan bcrypt.
Membuat dan Memverifikasi Hash
Berikut contoh controller untuk registrasi dan login:
<?php
namespace App\Http\Controllers\Auth;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
class RegisteredUserController
{
public function store(Request $request)
{
$validated = $request->validate([
'email' => 'required|email|unique:users',
'password' => 'required|string|max:128|confirmed',
]);
$user = User::create([
'email' => $validated['email'],
'password' => Hash::make($validated['password']),
]);
return redirect()->route('dashboard');
}
}
Dan bagian login:
<?php
$user = User::where('email', $request->email)->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
// Kredensial salah; terapkan rate limiting
return back()->withErrors(['email' => 'Kredensial yang kamu masukkan salah.']);
}
// Rehash otomatis jika work factor atau algoritma berubah
if (Hash::needsRehash($user->password)) {
$user->update(['password' => Hash::make($request->password)]);
}
// Login berhasil
Hash::check() aman dari timing attack dan melempar RuntimeException jika algoritma hash tidak cocok dengan driver yang dikonfigurasi. Hash::needsRehash() memeriksa apakah hash perlu di-upgrade sesuai konfigurasi saat ini.
Konfigurasi config/hashing.php
Konfigurasi hashing Laravel dapat diatur secara terpusat di config/hashing.php:
return [
'driver' => env('HASH_DRIVER', 'bcrypt'),
'bcrypt' => [
'rounds' => env('BCRYPT_ROUNDS', 12),
],
'argon' => [
'memory' => env('ARGON_MEMORY', 65536),
'threads'=> env('ARGON_THREADS', 1),
'time' => env('ARGON_TIME', 4),
],
'rehash_on_login' => true,
];
Contoh baris di .env:
HASH_DRIVER=bcrypt
BCRYPT_ROUNDS=12
Jika kamu ingin beralih ke Argon2id untuk seluruh aplikasi, cukup ubah HASH_DRIVER=argon2id di .env tanpa mengubah satu baris pun di controller.
Rehash-on-Login: Upgrade Hash Tanpa Memaksa Reset Password
Konsep rehash-on-login sederhana. Saat pengguna login berhasil, aplikasi memeriksa apakah hash yang tersimpan masih memenuhi standar terbaru. Jika belum—misalnya cost factor dinaikkan dari 10 ke 12—aplikasi membuat hash baru dengan parameter terkini dan menyimpannya ke database, menggantikan hash lama.
Dengan pendekatan ini, pengguna yang aktif login rutin akan mendapatkan hash baru secara bertahap. Pengguna yang jarang login tetap menggunakan hash lama sampai login berikutnya. Kamu tidak perlu memaksa seluruh basis pengguna mengganti password sekaligus, yang biasanya menciptakan gangguan pengalaman pengguna.
Implementasi di PHP native menggunakan password_needs_rehash() dan di Laravel menggunakan Hash::needsRehash() telah ditunjukkan di bagian sebelumnya. Keduanya mengikuti alur yang sama: verifikasi dulu, baru cek apakah rehash diperlukan setelah verifikasi berhasil.
Migrasi dari MD5 dan SHA-1 ke Algoritma Modern
Kamu tidak dapat langsung mengonversi hash MD5 atau SHA-1 menjadi bcrypt atau Argon2id tanpa password asli, karena fungsi hash satu arah tidak dapat dibalik. Strategi yang aman adalah migrasi saat login, juga dikenal sebagai lazy migration:
- Saat pengguna login, deteksi apakah hash di database menggunakan algoritma lama (misalnya dengan awalan hash atau tanda algoritma yang tersimpan di kolom terpisah).
- Verifikasi password dengan algoritma lama yang sesuai dengan implementasi lama kamu, misalnya
md5($password . $salt). - Jika cocok, buat hash modern dengan
password_hash()atauHash::make(), lalu simpan dan timpa hash lama di database. - Pengguna yang belum login tetap menggunakan hash lama sampai login berikutnya. Pertimbangkan memaksa reset password untuk akun yang tergolong rentan.
Jangan pernah menyimpan password plaintext sementara selama proses migrasi.
Rate Limiting pada Endpoint Login
Hashing yang kuat tidak cukup jika endpoint login tanpa perlindungan. Tanpa rate limiting, penyerang bisa mencoba ribuan kombinasi password secara berulang untuk melakukan brute force atau credential stuffing, terutama jika database sebelumnya sudah bocor dan mereka mengetahui password pengguna dari layanan lain.
Di Laravel, aktifkan rate limiting menggunakan RateLimiter dengan middleware throttle, misalnya throttle:5,1 untuk membatasi lima percobaan per menit. Kamu bisa menerapkan batasan per email dan/atau IP, serta memberikan lockout sementara setelah gagal berulang kali. Untuk panduan lengkap implementasi rate limiting di Laravel, baca artikel rate limiting Laravel.
Masalah Umum dan Cara Menghindarinya
Berikut adalah sejumlah kesalahan yang sering ditemukan dalam penyimpanan password dan cara mengatasi:
Menyimpan password plaintext atau menggunakan enkripsi dua arah seperti AES dan RSA berarti semua password langsung terekspos jika kunci atau database bocor. Gunakan selalu hashing satu arah.
Menggunakan MD5, SHA-1, atau SHA-256 untuk password berisiko tinggi karena algoritma ini terlalu cepat dan mudah dicrack oleh GPU. Gunakan bcrypt atau Argon2id sebagai penggantinya.
Membuat algoritma hash sendiri atau "custom crypto" adalah ide buruk. Kriptografi adalah bidang yang kompleks dan mudah menghasilkan kesalahan yang tidak terlihat. Percayakan pada fungsi standar yang diuji oleh komunitas kriptografi.
Membuat salt secara manual, statis, atau hardcoded dalam kode membuat hash rentan terhadap rainbow table dan deteksi duplikasi. Biarkan password_hash() dan Hash::make() menghasilkan salt otomatis.
Cost factor terlalu rendah (di bawah 10) membuat hash mudah dicrack offline. Cost terlalu tinggi dapat menyebabkan denial of service pada server. Benchmark hardware produksi kamu dan targetkan waktu eksekusi 250 hingga 500 milidetik per hash.
Menyimpan pepper di database sama dengan hash menghilangkan manfaat defense-in-depth. Simpan pepper di luar database, seperti di .env atau KMS.
Membandingkan hash dengan == atau === membuka kerangka timing attack. Gunakan password_verify() atau Hash::check().
Tidak melakukan rehash setelah upgrade cost atau algoritma berarti hash lama tetap lemah selamanya. Terapkan password_needs_rehash() atau Hash::needsRehash() pada alur login.
Password yang melebihi 72 byte dengan bcrypt akan terpotong dan kehilangan entropi. Batasi panjang password di aplikasi atau beralih ke Argon2id.
Menggunakan Argon2i sendirian untuk password kurang direkomendasikan OWASP karena kurang tahan terhadap GPU. Pilih Argon2id.
Tanpa rate limiting pada login, aplikasi rentan terhadap brute force dan credential stuffing. Aktifkan rate limiting pada endpoint login dan registrasi.
Checklist Keamanan Password
Sebelum mengirimkan aplikasi ke production, pastikan hal-hal berikut sudah terpenuhi:
- Gunakan Argon2id untuk sistem baru, atau bcrypt dengan cost minimal 10 (12 disarankan) sebagai alternatif.
- Biarkan runtime menghasilkan salt secara otomatis. Jangan buat salt manual atau simpan di kolom terpisah.
- Simpan hash di kolom minimal 255 karakter untuk mengantisipasi perubahan ukuran hash di masa depan.
- Gunakan
password_verify()atauHash::check()untuk verifikasi login. Hindari perbandingan string biasa. - Terapkan rehash-on-login dengan
password_needs_rehash()atauHash::needsRehash(). - Batasi panjang password (misalnya 64 hingga 128 karakter) atau gunakan Argon2id untuk menghindari batasan 72 byte bcrypt.
- Simpan pepper di luar database (
.env, environment variable, atau KMS) sebagai defense-in-depth jika diperlukan. - Aktifkan rate limiting pada endpoint login dan registrasi.
- Jangan klaim sistem "100% tidak bisa dibobol". Asumsikan database dapat bocor dan siapkan rencana respons, seperti memaksa reset password.
- Audit kode production untuk penggunaan
md5(),sha1(),sha256(), dan enkripsi dua arah pada password.
Penutup
Menyimpan password dengan aman bukan tentang menciptakan algoritma rahasia buatan sendiri, tetapi tentang memahami dan menerapkan standar industri yang sudah teruji. Hash satu arah adalah keharusan; plaintext, MD5, SHA-1, dan enkripsi dua arah tidak boleh pernah digunakan untuk menyimpan kredensial pengguna.
Pilih Argon2id untuk sistem baru, atau bcrypt dengan cost 12 sebagai alternatif andal. Gunakan password_hash() dan password_verify() di PHP native, atau Facade Hash di Laravel, dengan konfigurasi yang tepat. Terapkan rehash-on-login agar hash lama di-upgrade secara transparan saat pengguna login, batasi panjang password untuk menghindari batasan 72 byte bcrypt, simpan pepper di luar database jika ingin lapisan pertahanan tambahan, dan aktifkan rate limiting pada login.
Periksa kembali codebase aplikasi PHP atau Laravel kamu hari ini. Pastikan tidak lagi ada jejak md5() atau sha1() pada password, kolom password yang terlalu pendek, atau implementasi rehash yang belum ada. Keamanan password pengguna tergantung pada baris kode yang kamu tulis.
Untuk referensi teknis lebih lanjut, kamu bisa membaca dokumentasi PHP manual tentang password_hash(), OWASP Password Storage Cheat Sheet, dan dokumentasi Laravel tentang Hashing.
Jika kamu ingin mendalami topik keamanan dan autentikasi terkait, baca artikel tentang Authentication dan Cara Kerjanya.
Fitur komentar belum diaktifkan oleh administrator.