
Hari ini kita akan melihat cara terbaik untuk menyimpan kata sandi dalam database dan bagaimana platform terkenal memecahkan masalah ini.
Plaintext
Ketika muncul pertanyaan tentang menyimpan kata sandi, tentu saja, ide pertama adalah dengan menuliskannya terbuka di papan nama yang sesuai dalam database. Dan semuanya akan baik-baik saja jika pelanggan tidak dapat benar-benar mengaksesnya secara langsung. Tetapi, sayangnya, injeksi SQL yang terkenal itu terkadang masih berfungsi di berbagai aplikasi web, belum lagi potensi kerentanan lainnya. Dalam hal keamanan, umumnya diterima untuk mengambil yang terburuk dan menyiapkan rencana aksi dan perlindungan bahkan dalam kasus seperti itu. Kami berasumsi bahwa penyerang telah menemukan celah dalam aplikasi web, dengan satu atau lain cara dengan senang hati membongkar tabel dengan nama pengguna dan kata sandi dan kemudian membuangnya sesuai keinginan. Secara umum, tindakan selanjutnya adalah sebagai berikut:
- melakukan tindakan tidak sah atas nama pengguna menggunakan kredensial mereka pada sumber daya yang rentan: misalnya, kartu bank diikat ke akun, dan sekarang penyerang dapat menggunakannya;
- upaya untuk menggunakan kata sandi yang diterima pada sumber daya lain: jauh dari biasanya, pengguna, mengikuti saran, membuat kata sandi baru untuk layanan yang berbeda setiap kali;
- upaya untuk mengidentifikasi aturan untuk membuat kata sandi dan menuju ke poin kedua: beberapa membentuk aturan untuk menghasilkan kata sandi, sebagai akibatnya, kata sandi pada sumber daya yang berbeda berbeda, tetapi mereka mematuhi aturan yang sama yang dapat dideteksi;
- eskalasi hak istimewa: kata sandi administrator juga dapat disimpan dalam tabel yang sama, dengan pengetahuan yang kadang-kadang Anda dapat kontrol penuh atas server.
Hashing Enkripsi
Idenya segera ternyata tidak begitu baik. Apa yang harus dilakukan Akan sangat bagus untuk menyimpan kata sandi dalam bentuk terenkripsi. Kemudian, bahkan jika mereka dihapus, mereka tidak akan dapat pulih, atau setidaknya mereka akan menghabiskan terlalu banyak waktu untuk itu. Di sini pilihan muncul antara dua cabang pengembangan: mengenkripsi kata sandi atau hash. Para pengembang memilih yang kedua, dan, pada prinsipnya, jelas mengapa. Bandingkan pelamar kami untuk karakteristik yang berbeda:
- Masukan tenaga kerja. Enkripsi membutuhkan waktu lebih lama, dan apa pun konversi yang kita pilih, itu harus dilakukan dengan setiap pemeriksaan kata sandi. Salah satu persyaratan untuk fungsi hash adalah kecepatan eksekusi.
- Panjang nilai output. Hasil enkripsi panjang variabel, hasil hash selalu sama, dan menyimpan data yang seragam dalam database sangat mudah. Belum lagi fakta bahwa panjang kata sandi dalam bentuk terenkripsi akan memberikan beberapa informasi tentang panjang kata sandi asli. Panjang yang sama, bagaimanapun, mengarah pada kemungkinan tabrakan, tetapi lebih pada itu di bawah ini.
- Manajemen kunci. Enkripsi memerlukan kunci, yang juga harus disimpan di suatu tempat dan berharap tidak ada yang menemukannya. Bagaimanapun, generasi kunci dan manajemen adalah cerita yang terpisah (mereka tidak boleh lemah, mereka perlu diubah secara teratur, dan sebagainya).
- Kemungkinan konflik. Saat mengenkripsi, output dari data input yang berbeda akan selalu berbeda juga. Dengan hashing, ini tidak selalu terjadi. Panjang hash konstan berarti bahwa himpunan nilai-nilai output dari fungsi hash terbatas, yang mengarah pada kemungkinan tabrakan. Artinya, katakanlah pengguna benar-benar bingung dan menghasilkan kata sandi panjang yang sangat keren, yang memiliki karakter khusus, angka, dan huruf dalam huruf kecil dan besar. Penyerang memasuki kata sandi "admin" yang tidak kalah keren di bidang kata sandi. Server melakukan hash untuk memeriksa dan membandingkan hash. Hash cocok. Sayang sekali.
Dengan demikian, dengan skor 3: 1, hashing menang. Tetapi apakah mungkin untuk berhenti di situ?
Jawabannya adalah tidak.
Serangan Kata Sandi Hashed
Jadi, penyerang mendapatkan meja kami dengan nama pengguna dan kata sandi. Kata sandi sekarang di-hash, tetapi ini tidak menghentikan penyerang kita, dan dia serius bermaksud memulihkannya. Kemungkinan tindakannya:
- dictionary bruteforce: jika penyerang tidak berhasil dengan kata sandi referensi administrator, ia akan membuka kamus kata sandi populer dan mencoba peruntungannya dengan hash;
- tabel pelangi: secara umum hari ini, mungkin dia tidak perlu menghitung apa pun dan memilah-milah kamus. Ini akan cukup untuk beralih ke tabel pelangi di jaringan. Tabel pelangi berisi nilai hash yang sudah dihitung oleh seseorang sebelumnya dan data input yang sesuai. Penting untuk dicatat bahwa karena tabrakan, kata sandi yang akan ditawarkan oleh tabel pelangi tidak harus menjadi yang digunakan pengguna. Nilai yang dihitung sudah untuk MD5, SHA1, SHA256, SHA512, serta untuk modifikasi mereka dan beberapa lainnya. Anda dapat mencoba membalik hash, misalnya, di sini ;
- pencarian lengkap: jika ini tidak membantu, Anda harus menggunakan kekerasan dan memilah-milah semua kata sandi yang mungkin berturut-turut sampai hash yang dihitung akhirnya cocok.
Dalam kasus yang paling umum, penyerang harus memecahkan kata sandi. Dan di sini keberhasilannya akan tergantung, antara lain, pada kecepatan komputasi fungsi hash. Perbandingan waktu hash dapat ditemukan di
sini . Sebagai contoh, fungsi hash yang diimplementasikan Java pada 64-bit Windows 10 dengan 1 core Intel i7 2.60GHz dan 16GB RAM dijalankan jutaan kali untuk menghitung hash 36-karakter. Mereka menunjukkan hasil sebagai berikut:
MD5 - 627 ms
SHA-1 - 604 ms
SHA-256 - 739 ms
SHA-512 - 1056 ms
Tetapi hari ini bruteforce dapat diparalelkan dan berjalan beberapa kali lebih cepat pada GPU (juga pada APU, DSP dan FPGA). Namun, selain memilih algoritma yang lebih panjang dan output yang lebih lama, Anda dapat melakukan hal lain.
Hash hash
Untuk mencegah penyerang menggunakan tabel pelangi siap pakai, ada teknik untuk hashing kata sandi beberapa kali. Artinya, kita menghitung hash dari hash dari hash dari hash ... dan n kali (perlu, namun, jangan terlalu terlibat dengan ini, karena server juga harus melakukan ini selama verifikasi reguler kata sandi pengguna). Sekarang ini sangat sederhana menurut tabel pelangi dia tidak akan menemukan kata sandi, dan waktu untuk brute force akan meningkat secara signifikan. Tapi tidak ada yang akan menghentikan penyerang dari membuat tabel pelangi dari kamus kata sandi, mengetahui algoritma hashing. Selain itu, untuk kombinasi paling populer dari metode ini, tabel seperti itu telah dihasilkan:

"
Tambahkan garam secukupnya
Agar dia tidak bisa melakukan ini, kata sandi di-hash hari ini dengan tambahan garam.
Garam adalah string acak tambahan yang ditetapkan untuk kata sandi dan di-hash dengannya. Anda tidak dapat memulihkan kata sandi dari hash yang diperoleh dari tabel pelangi. Mengetahui garam dan hash output, penyerang ditakdirkan untuk brute force dan tidak ada tabel pra-dihitung kemungkinan besar akan membantunya.
Taksonomi penggaraman kata sandi:
1. Menurut prinsip pengasinan:
- garam unik untuk setiap pengguna: individu untuk setiap pengguna - dengan cara ini, jika garam diketahui oleh penyerang, setiap kata sandi harus dibasahi. Dan selain itu, bahkan jika dua pengguna berpikir dengan cara yang sama dan menghasilkan kata sandi yang identik, hash masih akan berbeda dalam output;
- garam global: sama untuk semua, digunakan untuk semua hash;
- baik itu, dan yang lainnya.
2. Menurut metode penyimpanan garam:
- dalam database: sebagai aturan, masing-masing garam disimpan dalam database yang sama dengan hash kata sandi; seringkali bahkan pada baris yang sama;
- dalam kode (baca: dalam konfigurasi): garam global biasanya disimpan bukan dalam database, tetapi, misalnya, dalam konfigurasi, sehingga pelanggar harus menghabiskan waktu pada pemilihannya.
Kami mengasumsikan bahwa masing-masing garam pengguna disimpan dalam database, garam global dalam konfigurasi. Penyerang mendapatkan akses ke database, dan dia tahu semua hash dan garam yang sesuai (garam global tidak disimpan dalam database, dan dia tidak tahu itu). Secara total, jika semua metode digabungkan, untuk mendapatkan kata sandi dalam bentuk yang jelas, seperti yang terjadi pada sistem pertama, ia, karena sangat memiliki tujuan, akan menghadapi kendala berikut:
- Dia tidak tahu garam global, jadi harus brutal.
- Dia tahu garam pengguna, tetapi dia tidak menyiapkan tabel dengan garam ini, jadi dia harus memecahkan kata sandi.
- Proses ini akan memakan waktu lebih banyak lagi karena Anda harus hash hash dan kali.
Bagaimana kata sandi menyimpan berbagai CMS
Wordpress
Sebelum versi 3.x, kata sandi diacak dengan MD5. Sekarang perpustakaan phpass digunakan. Secara default, salt ditetapkan ke kata sandi di depan dan string yang dihasilkan adalah MD5 2 ^ 8 kali.
Joomla
Sebelum versi 1.0.12, hanya MD5 digunakan. Pustaka phpass digunakan, secara default bcrypt dengan garam dan pengulangan 2 ^ 10.
Drupal
Hingga versi 6 md5 tanpa garam. Pustaka phpass digunakan. Standarnya adalah asin sha512 dengan pengulangan 2 ^ 16.
Silverstripe
Gunakan Blowfish asin dengan 2 ^ 10 repetisi.
Umbraco
Gunakan HMACSHA256 dengan garam. Menggunakan garam global kedua yang ditentukan dalam konfigurasi.