Sesekali saya mendengar saran "Gunakan bcrypt untuk menyimpan kata sandi dalam PHP, aturan bcrypt".
Tapi apa itu bcrypt
? PHP tidak menawarkan fungsi seperti itu, Wikipedia mengoceh tentang utilitas file-enkripsi dan pencarian Web hanya mengungkapkan beberapa implementasi Blowfish dalam berbagai bahasa. Sekarang Blowfish juga tersedia di PHP via mcrypt
, tetapi bagaimana itu membantu menyimpan kata sandi? Blowfish adalah sandi tujuan umum, ia bekerja dua cara. Jika itu bisa dienkripsi, itu bisa didekripsi. Kata sandi memerlukan fungsi hashing satu arah.
Apa penjelasannya?
bcrypt
algoritma hashing satu arah versus skema enkripsi dalam jawaban saya . Ada seluruh kesalahpahaman yangbcrypt
hanya Blowfish padahal sebenarnya memiliki jadwal kunci yang sama sekali berbeda yang memastikan bahwa teks biasa tidak dapat dipulihkan dari teks sandi tanpa mengetahui keadaan awal sandi (garam, putaran, kunci).Jawaban:
bcrypt
adalah algoritma hashing yang dapat diskalakan dengan perangkat keras (melalui sejumlah putaran yang dapat dikonfigurasi). Kelambanan dan ronde yang berulang memastikan bahwa penyerang harus menggunakan dana besar dan perangkat keras untuk dapat memecahkan kata sandi Anda. Tambahkan ke garam per kata sandi (bcrypt
MEMBUTUHKAN garam) dan Anda dapat yakin bahwa serangan hampir tidak mungkin terjadi tanpa jumlah dana atau perangkat keras yang menggelikan.bcrypt
menggunakan algoritma Eksblowfish untuk kata sandi hash. Meskipun fase enkripsi Eksblowfish dan Blowfish persis sama, fase jadwal kunci dari Eksblowfish memastikan bahwa keadaan selanjutnya bergantung pada garam dan kunci (kata sandi pengguna), dan tidak ada negara yang dapat dikomputasi tanpa sepengetahuan keduanya. Karena perbedaan kunci ini,bcrypt
adalah algoritma hashing satu arah. Anda tidak dapat mengambil kata sandi teks biasa tanpa mengetahui garam, putaran dan kunci (kata sandi). [ Sumber ]Cara menggunakan bcrypt:
Menggunakan PHP> = 5.5-DEV
Fungsi hashing kata sandi kini telah dibangun langsung ke dalam PHP> = 5.5 . Anda sekarang dapat menggunakan
password_hash()
untuk membuatbcrypt
hash kata sandi apa pun:Untuk memverifikasi kata sandi yang diberikan pengguna terhadap hash yang ada, Anda dapat menggunakan
password_verify()
seperti itu:Menggunakan PHP> = 5.3.7, <5.5-DEV (juga RedHat PHP> = 5.3.3)
Ada pustaka kompatibilitas pada GitHub yang dibuat berdasarkan kode sumber dari fungsi-fungsi di atas yang aslinya ditulis dalam C, yang menyediakan fungsionalitas yang sama. Setelah pustaka kompatibilitas diinstal, penggunaannya sama dengan di atas (minus notasi susunan steno jika Anda masih di cabang 5.3.x).
Menggunakan PHP <5.3.7 ( DEPRECATED )
Anda dapat menggunakan
crypt()
fungsi untuk menghasilkan bcrypt hashes dari string input. Kelas ini dapat secara otomatis menghasilkan garam dan memverifikasi hash yang ada terhadap input. Jika Anda menggunakan versi PHP yang lebih tinggi atau sama dengan 5.3.7, sangat disarankan Anda menggunakan fungsi bawaan atau pustaka compat . Alternatif ini disediakan hanya untuk tujuan historis.Anda dapat menggunakan kode ini seperti ini:
Atau, Anda juga dapat menggunakan Kerangka Hashing PHP Portabel .
sumber
mt_rand()
juga diunggulkan menggunakan waktu saat ini dan ID proses saat ini. Silakan lihatGENERATE_SEED()
di/ext/standard/php_rand.h
.crypt()
adalah peer-review dan diverifikasi. Kode di atas memanggil PHPcrypt()
, yang memanggilcrypt()
fungsi POSIX . Semua kode di atas tidak lebih menghasilkan garam acak (yang tidak harus aman secara kriptografi, garam tidak dianggap rahasia) sebelum meneleponcrypt()
. Mungkin Anda harus melakukan sedikit riset sendiri sebelum memanggil serigala.crypt()
) tunduk pada kerentanan keamanan pra-5.3.7, dan (sangat sedikit) tidak efisien pasca-5.3.7 - rincian masalah yang relevan dapat ditemukan di sini . Harap perhatikan juga bahwa API hashing kata sandi baru ( backwards compat lib ) sekarang merupakan metode yang disukai untuk mengimplementasikan hashing bcrypt kata sandi dalam aplikasi Anda.Jadi, Anda ingin menggunakan bcrypt? Luar biasa! Namun, seperti bidang kriptografi lainnya, Anda tidak harus melakukannya sendiri. Jika Anda perlu khawatir tentang hal-hal seperti mengelola kunci, atau menyimpan garam atau menghasilkan angka acak, Anda salah melakukannya.
Alasannya sederhana: sangat mudah untuk mengacaukan bcrypt . Bahkan, jika Anda melihat hampir setiap bagian kode pada halaman ini, Anda akan melihat bahwa itu melanggar setidaknya satu dari masalah umum ini.
Hadapi Itu, Kriptografi sulit.
Biarkan untuk para ahli. Biarkan untuk orang-orang yang tugasnya memelihara perpustakaan-perpustakaan ini. Jika Anda perlu mengambil keputusan, Anda salah melakukannya.
Sebagai gantinya, cukup gunakan perpustakaan. Ada beberapa tergantung pada kebutuhan Anda.
Perpustakaan
Berikut ini adalah rincian dari beberapa API yang lebih umum.
PHP 5.5 API - (Tersedia untuk 5.3.7+)
Mulai di PHP 5.5, API baru untuk hashing passwords sedang diperkenalkan. Ada juga perpustakaan kompatibilitas shim yang dikelola (oleh saya) untuk 5.3.7+. Ini memiliki manfaat menjadi peer-review dan implementasi yang mudah digunakan.
Sungguh, ini ditujukan untuk menjadi sangat sederhana.
Sumber:
Zend \ Crypt \ Password \ Bcrypt (5.3.2+)
Ini adalah API lain yang mirip dengan PHP 5.5 satu, dan melakukan tujuan yang sama.
Sumber:
PasswordLib
Ini adalah pendekatan yang sedikit berbeda untuk hashing kata sandi. Daripada hanya mendukung bcrypt, PasswordLib mendukung sejumlah besar algoritma hashing. Ini terutama berguna dalam konteks di mana Anda perlu mendukung kompatibilitas dengan sistem lama dan berbeda yang mungkin berada di luar kendali Anda. Ini mendukung sejumlah besar algoritma hashing. Dan didukung 5.3.2+
Referensi:
PHPASS
Ini adalah lapisan yang mendukung bcrypt, tetapi juga mendukung algoritma yang cukup kuat yang berguna jika Anda tidak memiliki akses ke PHP> = 5.3.2 ... Ini sebenarnya mendukung PHP 3.0+ (walaupun tidak dengan bcrypt).
Sumber daya
Catatan: Jangan gunakan alternatif PHPASS yang tidak di-host di openwall, itu adalah proyek yang berbeda !!!
Tentang BCrypt
Jika Anda perhatikan, setiap perpustakaan ini mengembalikan satu string. Itu karena cara BCrypt bekerja secara internal. Dan ada banyak jawaban tentang hal itu. Berikut adalah pilihan yang saya tulis, yang tidak akan saya salin / tempel di sini, tetapi tautkan ke:
md5
kata sandi lama ke bcryptBungkus
Ada banyak pilihan berbeda. Yang Anda pilih terserah Anda. Namun, saya akan SANGAT menyarankan agar Anda menggunakan salah satu perpustakaan di atas untuk menangani ini untuk Anda.
Sekali lagi, jika Anda menggunakan
crypt()
secara langsung, Anda mungkin melakukan sesuatu yang salah. Jika kode Anda menggunakanhash()
(ataumd5()
atausha1()
) secara langsung, Anda hampir pasti melakukan sesuatu yang salah.Cukup gunakan perpustakaan ...
sumber
mt_rand()
memiliki periode yang cukup tinggi, tetapi nilai benih hanya 32 bit. Jadi menggunakanmt_rand()
secara efektif membatasi Anda hanya untuk 32 bit entropi. Yang berkat Masalah Ulang Tahun berarti bahwa Anda memiliki kemungkinan tabrakan 50% hanya pada 7k garam yang dihasilkan (secara global). Karenabcrypt
menerima 128 bit garam, lebih baik menggunakan sumber yang dapat memasok semua 128 bit ;-). (pada 128 bit, kemungkinan tabrakan 50% terjadi pada hash 2e19) ...mt_rand
danuniqid
(dan karenanyalcg_value
danrand
) bukanlah pilihan pertama ...Anda akan mendapatkan banyak informasi dalam Cukup Dengan Tabel Pelangi: Yang Perlu Anda Ketahui Tentang Skema Kata Sandi Aman atau kerangka kerja hashing kata sandi PHP Portabel .
Tujuannya adalah untuk hash kata sandi dengan sesuatu yang lambat, sehingga seseorang yang mendapatkan basis data kata sandi Anda akan mati karena berusaha memaksakannya (penundaan 10 ms untuk memeriksa kata sandi tidak ada artinya bagi Anda, banyak bagi seseorang yang mencoba memaksakannya). Bcrypt lambat dan dapat digunakan dengan parameter untuk memilih seberapa lambat itu.
sumber
Anda dapat membuat hash satu arah dengan bcrypt menggunakan
crypt()
fungsi PHP dan mengirimkan garam Blowfish yang sesuai. Yang paling penting dari keseluruhan persamaan adalah bahwa A) algoritme belum dikompromikan dan B) Anda benar garam setiap kata sandi . Jangan gunakan garam aplikasi-lebar; yang membuka seluruh aplikasi Anda untuk menyerang dari satu set tabel Rainbow.PHP - Fungsi Crypt
sumber
crypt()
fungsi PHP , yang mendukung beberapa fungsi hashing kata sandi yang berbeda. Pastikan Anda tidak menggunakanCRYPT_STD_DES
atauCRYPT_EXT_DES
- salah satu dari jenis yang didukung lainnya baik-baik saja (dan termasuk bcrypt, dengan namaCRYPT_BLOWFISH
).crypt
memperlihatkan beberapa hash kata sandi, dengan bcrypt yang sesuai denganCRYPT_BLOWFISH
konstanta. Bcrypt saat ini merupakan algoritma terkuat yang didukung olehcrypt
dan beberapa lainnya yang didukungnya cukup lemah.Sunting: 2013.01.15 - Jika server Anda akan mendukungnya, gunakan solusi martinstoeckli sebagai gantinya.
Semua orang ingin membuat ini lebih rumit daripada itu. Fungsi crypt () melakukan sebagian besar pekerjaan.
Contoh:
Saya tahu itu harus jelas, tapi tolong jangan gunakan 'kata sandi' sebagai kata sandi Anda.
sumber
2y
daripada2a
.mcrypt_create_iv($size, MCRYPT_DEV_URANDOM)
sebagai sumber garam.bcrypt
.mcrypt_create_iv(17, MCRYPT_DEV_URANDOM)
,str_replace('+', '.', base64_encode($rawSalt))
,$salt = substr($salt, 0, 22);
Versi 5.5 dari PHP akan memiliki dukungan bawaan untuk BCrypt, fungsi
password_hash()
danpassword_verify()
. Sebenarnya ini hanya pembungkus di sekitar fungsicrypt()
, dan akan membuatnya lebih mudah untuk menggunakannya dengan benar. Ini menangani pembuatan garam acak yang aman, dan memberikan nilai default yang baik.Cara termudah untuk menggunakan fungsi ini adalah:
Kode ini akan memotong kata sandi dengan BCrypt (algoritma
2y
), menghasilkan garam acak dari sumber acak OS, dan menggunakan parameter biaya default (saat ini 10). Baris kedua memeriksa, apakah pengguna memasukkan kata sandi cocok dengan nilai hash yang sudah tersimpan.Jika Anda ingin mengubah parameter biaya, Anda dapat melakukannya seperti ini, meningkatkan parameter biaya sebesar 1, menggandakan waktu yang dibutuhkan untuk menghitung nilai hash:
Berbeda dengan
"cost"
parameter, yang terbaik adalah menghilangkan"salt"
parameter, karena fungsi sudah melakukan yang terbaik untuk membuat garam yang aman secara kriptografis.Untuk PHP versi 5.3.7 dan yang lebih baru, ada paket kompatibilitas , dari penulis yang sama yang membuat
password_hash()
fungsi. Untuk versi PHP sebelum 5.3.7 tidak ada dukungan untukcrypt()
dengan2y
, algoritma BCrypt unicode safe. Orang bisa menggantinya dengan2a
, yang merupakan alternatif terbaik untuk versi PHP sebelumnya.sumber
Pemikiran saat ini: hash harus paling lambat tersedia, bukan yang tercepat. Ini menekan meja pelangi serangan .
Juga terkait, tetapi pencegahan: Penyerang tidak boleh memiliki akses tak terbatas ke layar login Anda. Untuk mencegahnya: Siapkan tabel pelacakan alamat IP yang merekam setiap klik bersama dengan URI. Jika lebih dari 5 upaya untuk masuk berasal dari alamat IP yang sama dalam periode lima menit, blokir dengan penjelasan. Pendekatan sekunder adalah memiliki skema kata sandi dua tingkat, seperti yang dilakukan bank. Menempatkan lock-out untuk kegagalan pada pass kedua meningkatkan keamanan.
Rangkuman: memperlambat penyerang dengan menggunakan fungsi hash yang menghabiskan waktu. Juga, blokir pada terlalu banyak akses ke login Anda, dan tambahkan tingkat kata sandi kedua.
sumber
Inilah jawaban yang diperbarui untuk pertanyaan lama ini!
Cara yang tepat untuk kata sandi hash di PHP sejak 5.5 adalah dengan
password_hash()
, dan cara yang benar untuk memverifikasi mereka denganpassword_verify()
, dan ini masih berlaku di PHP 8.0. Fungsi-fungsi ini menggunakan hash bcrypt secara default, tetapi algoritma yang lebih kuat lainnya telah ditambahkan. Anda dapat mengubah faktor kerja (seberapa efektif enkripsi "kuat") melaluipassword_hash
parameter.Namun, meskipun masih cukup kuat, bcrypt tidak lagi dianggap canggih ; satu set algoritma hash kata sandi yang lebih baik telah tiba disebut Argon2 , dengan Argon2i, Argon2d, dan varian Argon2id. Perbedaan di antara mereka (seperti yang dijelaskan di sini ):
Dukungan Argon2i ditambahkan dalam PHP 7.2, dan Anda memintanya seperti ini:
dan dukungan Argon2id ditambahkan dalam PHP 7.3:
Tidak ada perubahan yang diperlukan untuk memverifikasi kata sandi karena string hash yang dihasilkan berisi informasi tentang algoritma, garam, dan faktor kerja apa yang digunakan saat itu dibuat.
Secara terpisah (dan agak berlebihan), libsodium (ditambahkan dalam PHP 7.2) juga menyediakan hashing Argon2 melalui
sodium_crypto_pwhash_str ()
dansodium_crypto_pwhash_str_verify()
fungsi, yang bekerja sangat mirip dengan PHP bawaan . Salah satu alasan yang mungkin untuk menggunakan ini adalah bahwa PHP kadang-kadang dapat dikompilasi tanpa libargon2, yang membuat algoritma Argon2 tidak tersedia untuk fungsi password_hash; PHP 7.2 dan lebih tinggi harus selalu mengaktifkan libsodium, tetapi mungkin tidak - tetapi setidaknya ada dua cara yang bisa Anda dapatkan pada algoritma itu. Inilah cara Anda dapat membuat hash Argon2id dengan libsodium (bahkan dalam PHP 7.2, yang sebaliknya tidak memiliki dukungan Argon2id)):Perhatikan bahwa tidak memungkinkan Anda menentukan garam secara manual; ini adalah bagian dari etos libsodium - jangan izinkan pengguna mengatur params ke nilai yang dapat membahayakan keamanan - misalnya tidak ada yang mencegah Anda mengirimkan string garam kosong ke
password_hash
fungsi PHP ; libsodium tidak membiarkan Anda melakukan hal konyol itu!sumber
Untuk kata sandi OAuth 2 :
sumber
Seperti yang kita semua tahu menyimpan kata sandi dalam teks yang jelas dalam database tidak aman. bcrypt adalah teknik kata sandi hashing. Ini digunakan untuk membangun keamanan kata sandi. salah satu fungsi bcrypt yang luar biasa adalah menyelamatkan kita dari peretas. Ia digunakan untuk melindungi kata sandi dari serangan peretasan karena kata sandi disimpan dalam bentuk bcrypt.
fungsi password_hash () digunakan untuk membuat hash kata sandi baru. Ini menggunakan algoritma hashing yang kuat & tangguh. Fungsi password_hash () sangat kompatibel dengan fungsi crypt (). Oleh karena itu, hash kata sandi yang dibuat oleh crypt () dapat digunakan dengan password_hash () dan sebaliknya. Fungsi password_verify () dan password_hash () hanya pembungkus di sekitar fungsi crypt (), dan mereka membuatnya lebih mudah untuk menggunakannya secara akurat.
SINTAKSIS
Algoritma berikut saat ini didukung oleh fungsi password_hash ():
PASSWORD_DEFAULT PASSWORD_BCRYPT PASSWORD_ARGON2I PASSWORD_ARGON2ID
Parameter: Fungsi ini menerima tiga parameter seperti yang disebutkan di atas dan dijelaskan di bawah:
kata sandi : Ini menyimpan kata sandi pengguna. algo : Ini adalah konstanta algoritma kata sandi yang digunakan terus-menerus sambil menunjukkan algoritma yang akan digunakan ketika hashing kata sandi terjadi. Opsi : Ini adalah array asosiatif, yang berisi opsi. Jika ini dihapus dan tidak termasuk, garam acak akan digunakan, dan pemanfaatan biaya standar akan terjadi. Kembali Nilai : Ini mengembalikan kata sandi hash pada keberhasilan atau Salah pada kegagalan.
Contoh :
Program-program di bawah ini menggambarkan fungsi password_hash () dalam PHP:
KELUARAN
sumber