Jika saya hash password sebelum menyimpannya di database saya, adalah yang cukup untuk mencegah mereka menjadi pulih oleh siapa saja?
Saya harus menunjukkan bahwa hal ini berkaitan hanya untuk pengambilan langsung dari database, dan tidak ada jenis serangan lainnya, seperti bruteforcing halaman login aplikasi, keylogger pada klien, dan tentu saja rubberhose kriptoanalisis (atau saat ini kita harus menyebutnya "Chocolate Kriptoanalisis").
Tentu saja dalam bentuk hash tidak akan mencegah serangan-serangan.
Catatan: jawaban Ini ditulis pada tahun 2013. Banyak hal telah berubah dalam tahun-tahun berikutnya, yang berarti bahwa jawaban ini terutama harus dilihat sebagai cara terbaik praktek yang digunakan untuk menjadi di tahun 2013.
Teori
Kita perlu untuk hash password sebagai second line of defence. Sebuah server yang dapat melakukan otentikasi pengguna tentu berisi, di suatu tempat di perut, beberapa data yang dapat digunakan untuk validate password. Sebuah sistem yang sangat sederhana hanya akan menyimpan password sendiri, dan validasi akan menjadi sebuah perbandingan sederhana. Tapi jika bermusuhan luar untuk mendapatkan sederhana sekilas isi dari file atau tabel database yang berisi password, maka penyerang akan belajar banyak. Sayangnya, seperti parsial, hanya-baca pelanggaran yang terjadi dalam praktek (yang tdk dpt ditemukan backup tape, dihentikan tapi tidak dihapus-out hard disk, merupakan buntut dari serangan injeksi SQL-kemungkinan yang lain). Lihat posting blog ini untuk pembahasan yang lebih rinci. Sejak keseluruhan isi dari server yang dapat memvalidasi password yang tentu cukup untuk memang memvalidasi password, penyerang yang diperoleh hanya-baca snapshot dari server yang berada dalam posisi untuk membuat sebuah kamus offline serangan: ia mencoba password potensial sampai pertandingan ditemukan. Ini tidak dapat dihindari. Jadi kami ingin membuat semacam serangan sekeras mungkin. Alat-alat kami yang berikut ini:
- Fungsi hash kriptografi: ini menarik objek matematika yang semua orang dapat menghitung secara efisien, namun tidak ada yang tahu bagaimana untuk membalikkan mereka. Ini terlihat baik untuk masalah - server bisa menyimpan hash password; ketika disajikan dengan diduga password, server yang hanya memiliki hash ini untuk melihat jika mendapat nilai yang sama; namun, mengetahui hash tidak mengungkapkan kata sandi sendiri.
- Garam: di antara keuntungan dari penyerang atas the defender adalah parallelism. Penyerang biasanya diperebutkan daftar seluruh hash password, dan tertarik dalam memecahkan banyak dari mereka sebanyak mungkin. Dia mungkin mencoba untuk menyerang beberapa di parallels. Misalnya, penyerang dapat mempertimbangkan salah satu potensi password, hash, dan kemudian membandingkan dengan nilai 100 hashed password; ini berarti bahwa penyerang shares yang cost hashing selama beberapa diserang password. Serupa optimasi precomputed tables, termasuk rainbow tabel; ini adalah masih paralelisme, dengan ruang-waktu berubah koordinat. Karakteristik umum dari semua serangan yang menggunakan paralelisme adalah bahwa mereka bekerja selama beberapa password yang diolah dengan exact hash yang sama function. Pengasinan adalah tentang menggunakan tidak one fungsi hash, tapi a banyak berbeda hash functions; idealnya, setiap contoh hashing password harus menggunakan sendiri fungsi hash. Sebuah salt adalah cara untuk memilih fungsi hash antara keluarga besar dari fungsi hash. Benar diterapkan garam benar-benar akan menggagalkan paralel serangan (termasuk tabel pelangi).
- Kelambatan: komputer menjadi lebih cepat dari waktu ke waktu (Gordon Moore, salah satu pendiri Intel, berteori itu dalam bukunya yang terkenal hukum). Otak manusia tidak. Ini berarti bahwa penyerang bisa "coba" lebih dan lebih potensial password seperti tahun-tahun berlalu, sementara pengguna tidak dapat mengingat lebih banyak dan lebih kompleks password (atau tegas menolak untuk). Untuk melawan tren itu, kita dapat membuat hashing inherently slow dengan mendefinisikan fungsi hash untuk menggunakan banyak internal iterasi (ribuan, mungkin jutaan). Kami memiliki beberapa standar fungsi hash kriptografi; yang paling terkenal adalah MD5 dan SHA keluarga. Membangun secure hash fungsi dari operasi dasar ini jauh dari mudah. Ketika kriptografer ingin melakukan itu, mereka berpikir keras, kemudian lebih keras, dan mengatur sebuah turnamen di mana fungsi-fungsi yang saling bertarung sengit. Ketika ratusan kriptografer menggerogoti dan tergores dan menekan pada fungsi selama beberapa tahun dan menemukan tidak ada yang buruk untuk mengatakan tentang hal itu, kemudian mereka mulai mengakui bahwa mungkin bahwa fungsi tertentu bisa dianggap sebagai lebih atau kurang aman. Ini adalah hanya apa yang terjadi di SHA-3 kompetisi. Kami have untuk menggunakan cara ini merancang fungsi hash karena kita tahu tidak ada cara yang lebih baik. Secara matematis, kita tidak tahu apakah aman fungsi hash benar-benar ada; kita hanya memiliki "calon" (yang's perbedaan antara "itu tidak dapat rusak" dan "tak seorang pun di dunia tahu bagaimana untuk istirahat"). Dasar fungsi hash, bahkan jika aman as hash function, adalah tidak tepat untuk hashing password, karena:
- itu adalah tawar, yang memungkinkan untuk paralel serangan (rainbow tabel untuk MD5 atau SHA-1 dapat diperoleh secara gratis, anda bahkan tidak perlu untuk menghitung ulang mereka sendiri);
- itu adalah cara yang terlalu cepat, dan akan lebih cepat dengan kemajuan teknologi. Dengan GPU (yaitu off-the-shelf konsumen produk yang semua orang bisa beli), hashing rate adalah dihitung dalam miliaran password per detik. Jadi kita perlu sesuatu yang lebih baik. Hal ini terjadi bahwa menampar bersama-sama fungsi hash dan garam, dan iterasi ini, adalah tidak mudah untuk dilakukan daripada merancang sebuah fungsi hash -- setidaknya, jika anda ingin hasil yang aman. Ada lagi, anda harus bergantung pada standar konstruksi yang telah selamat dari serangan terus menerus dari vindicative kriptografer.
Baik Password Fungsi Hashing
PBKDF2
PBKDF2 berasal dari PKCS#5. Hal ini parameterized dengan jumlah iterasi (integer, setidaknya 1, tidak ada batas atas), garam (sewenang-wenang urutan byte, tidak ada kendala pada panjang), yang diperlukan output panjang (PBKDF2 dapat menghasilkan output yang dapat dikonfigurasi, suhu udara), dan "yang mendasari PRF". Dalam prakteknya, PBKDF2 selalu digunakan dengan HMAC, yang itu sendiri merupakan konstruksi yang dibangun di atas yang mendasari fungsi hash. Jadi ketika kita mengatakan "PBKDF2 dengan SHA-1", kami benar-benar berarti "PBKDF2 dengan HMAC dengan SHA-1". Keuntungan dari PBKDF2:
- Telah ditentukan untuk waktu yang lama, tampaknya tanpa cedera untuk saat ini.
- Sudah dilaksanakan di berbagai framework (misalnya ini disediakan dengan .NET).
- Sangat dikonfigurasi (meskipun beberapa implementasi yang tidak membiarkan anda memilih fungsi hash, misalnya satu .NET adalah untuk SHA-1).
- Menerima NIST berkah (modulo perbedaan antara hashing dan kunci turunannya; lihat nanti).
- Dikonfigurasi output panjang (sekali lagi, lihat nanti). Kelemahan dari PBKDF2:
- CPU-intensif saja, sehingga setuju untuk optimasi yang tinggi dengan GPU (bek dasar server yang tidak generik hal, yaitu PC, tapi penyerang dapat menghabiskan anggaran lebih berupa hardware, yang akan memberinya tepi).
- Anda masih harus mengatur parameter sendiri (garam generasi dan penyimpanan, jumlah iterasi encoding...). Ada standar pengkodean untuk PBKDF2 parameter tetapi menggunakan ASN.1 sehingga kebanyakan orang akan menghindari itu jika mereka dapat (ASN.1 bisa rumit untuk menangani untuk non-ahli).
bcrypt
bcrypt dirancang dengan menggunakan kembali dan memperluas unsur-unsur blok cipher yang disebut Blowfish. Iterasi menghitung kekuatan dari dua, yang merupakan laki-laki kurang dapat dikonfigurasi dari PBKDF2, tapi cukup jadi demikian. Ini adalah inti password hashing mekanisme di OpenBSD sistem operasi. Keuntungan dari bcrypt:
- Tersedia banyak implementasi dalam berbagai bahasa (lihat link di bagian akhir halaman Wikipedia).
- Lebih tahan terhadap GPU; hal ini disebabkan rincian desain internal. Yang bcrypt penulis membuatnya jadi secara sukarela: mereka kembali Blowfish karena Blowfish didasarkan pada internal RAM tabel yang terus-menerus diakses dan dimodifikasi sepanjang pengolahan. Hal ini membuat hidup jauh lebih sulit untuk siapapun yang ingin mempercepat bcrypt dengan GPU (GPU tidak pandai membuat banyak akses memori secara paralel). Lihat di sini untuk beberapa diskusi.
- Output standar pengkodean yang meliputi garam, jumlah iterasi dan output sebagai salah satu sederhana untuk menyimpan karakter string dari karakter yang dapat dicetak. Kelemahan dari bcrypt:
- Ukuran Output tetap: 192 bit.
- Sementara bcrypt baik untuk menggagalkan GPU, hal ini masih dapat benar-benar dioptimalkan dengan FPGA: modern FPGA chip memiliki banyak kecil tertanam RAM blok yang sangat nyaman untuk menjalankan banyak bcrypt implementasi secara paralel dalam satu chip. Itu telah dilakukan.
- Masukan password ukuran terbatas 51 karakter. Dalam rangka untuk menangani lagi password, salah satu telah untuk menggabungkan bcrypt dengan fungsi hash (anda hash password dan kemudian menggunakan nilai hash sebagai "password" untuk bcrypt). Menggabungkan kriptografi primitif dikenal untuk menjadi berbahaya (lihat di atas) sehingga game tersebut tidak dapat direkomendasikan secara umum.
scrypt
scrypt adalah jauh lebih baru konstruksi (dirancang pada tahun 2009) yang membangun di atas PBKDF2 dan stream cipher yang disebut Salsa20/8, tapi ini hanya alat-alat di sekitar inti kekuatan dari scrypt, yang RAM. scrypt telah dirancang untuk inheren menggunakan banyak RAM (ini menghasilkan beberapa pseudo-random byte, kemudian berulang kali membacanya dalam pseudo-random sequence). "Banyak RAM" adalah sesuatu yang sulit untuk membuat paralel. Dasar KOMPUTER baik RAM di akses, dan tidak akan mencoba untuk membaca puluhan berhubungan RAM byte secara bersamaan. Seorang penyerang dengan GPU atau FPGA akan ingin melakukan itu, dan akan menemukan itu sulit. Keuntungan dari scrypt:
- Sebuah PC, yaitu apa defender akan digunakan saat hashing password, adalah yang paling efisien platform (atau cukup dekat) untuk komputasi scrypt. Penyerang tidak lagi mendapat dorongan dengan menghabiskan uangnya pada GPU atau FPGA.
- Salah satu cara yang lebih untuk menyempurnakan fungsi: ukuran memori. Kelemahan dari scrypt:
- Masih baru (saya sendiri aturan praktis adalah untuk menunggu setidaknya 5 tahun dari paparan umum, sehingga tidak ada scrypt untuk produksi sampai dengan tahun 2014 - tapi, tentu saja, yang terbaik adalah jika other people mencoba scrypt di produksi, karena hal ini memberikan ekstra exposure).
- Tidak banyak tersedia, siap-untuk-menggunakan implementasi karena berbagai bahasa.
- Belum jelas apakah CPU / RAM mix yang optimal. Untuk masing-masing pseudo-random RAM mengakses, scrypt masih menghitung fungsi hash. Cache miss akan menjadi sekitar 200 jam siklus, satu SHA-256 doa lebih dekat ke 1000. Mungkin ada ruang untuk perbaikan di sini.
- Belum parameter lain untuk mengkonfigurasi: ukuran memori.
OpenPGP Iterasi Dan Asin S2K
Saya mengutip satu ini karena anda akan menggunakannya jika anda melakukan password berbasis enkripsi file dengan GnuPG. Alat itu mengikuti format OpenPGP yang mendefinisikan sendiri password hashing fungsi, yang disebut "S2K Sederhana", "Asin S2K" dan "Iterasi dan Asin S2K". Hanya yang ketiga bisa dianggap "baik" dalam konteks ini jawabannya. Hal ini didefinisikan sebagai hash dari string yang sangat panjang (dapat dikonfigurasi, hingga sekitar 65 megabyte) yang terdiri dari pengulangan 8-byte garam dan password. Sejauh ini hal-hal pergi, OpenPGP's Iterasi Dan Asin S2K ini layak; hal ini dapat dianggap sebagai mirip dengan PBKDF2, dengan kurang konfigurabilitas. Anda akan sangat jarang menemukan hal luar OpenPGP, sebagai stand-alone fungsi.
Unix "crypt"
Beberapa sistem Unix-like (misalnya Linux), untuk memvalidasi password pengguna, menggunakan iterasi dan asin varian crypt() berdasarkan fungsi baik fungsi hash, dengan ribuan iterasi. Ini adalah cukup baik. Beberapa sistem juga dapat menggunakan bcrypt, mana yang lebih baik. Tua crypt() fungsi, berdasarkan DES blok cipher, adalah not cukup baik:
- Itu adalah lambat dalam perangkat lunak tetapi cepat dalam perangkat keras, dan dapat dibuat dengan cepat dalam perangkat lunak juga, tapi hanya ketika komputasi beberapa kasus secara paralel (teknik yang dikenal sebagai SWAR atau "bitslicing"). Dengan demikian, penyerang pada keuntungan.
- Masih cukup cepat, dengan hanya 25 iterasi.
- Memiliki 12-bit garam, yang berarti bahwa garam reuse akan terjadi cukup sering.
- Itu memotong password dengan 8 karakter (karakter luar kedelapan diabaikan) dan juga tetes atas sedikit dari masing-masing karakter (jadi anda lebih atau kurang terjebak dengan ASCII). Tapi yang lebih baru varian, yang aktif secara default, akan baik-baik saja.
Bad Password Fungsi Hashing
Tentang segala sesuatu yang lain, khususnya hampir setiap video amatir metode bahwa orang-orang terus-menerus menciptakan. Untuk beberapa alasan, banyak pengembang bersikeras merancang fungsi sendiri, dan tampaknya berasumsi bahwa "aman kriptografi desain" yang berarti "melempar bersama-sama setiap jenis kriptografi atau non-operasi kriptografi yang dapat berpikir". Lihat pertanyaan untuk contoh. Prinsip yang mendasari tampaknya bahwa semata-mata kompleksitas yang dihasilkan benar-benar kusut berantakan instruksi akan membingungkan penyerang. Dalam prakteknya, meskipun, pengembang sendiri akan menjadi lebih bingung oleh ciptaan-nya sendiri dari penyerang. Kompleksitas yang lebih buruk. Buatan sendiri adalah buruk. Baru lebih buruk. Jika anda ingat bahwa, anda'll menghindari 99% dari masalah yang berkaitan dengan hashing password, atau kriptografi, atau bahkan keamanan secara umum. Hashing Password di sistem operasi Windows yang digunakan untuk menjadi mindbogglingly mengerikan dan sekarang hanya mengerikan (tawar, non-mengulangi MD4).
Kunci Turunannya
Sampai sekarang, kami menganggap pertanyaan hashing passwords. Dekat masalah adalah tentang mengubah password menjadi kunci simetrik yang dapat digunakan untuk enkripsi; ini disebut key derivasi dan adalah hal pertama yang anda lakukan ketika anda "mengenkripsi file dengan password". Hal ini dimungkinkan untuk membuat dibikin contoh dari fungsi hashing password yang aman untuk tujuan menyimpan password validasi token, tapi mengerikan ketika datang untuk menghasilkan kunci simetris; dan sebaliknya adalah sama-sama mungkin. Tetapi contoh-contoh ini sangat "buatan". Untuk practical fungsi seperti yang dijelaskan di atas:
- Output dari fungsi hashing password dapat diterima sebagai kunci simetris, mungkin setelah pemotongan dengan ukuran yang dibutuhkan.
- Kunci Derivasi Fungsi dapat berfungsi sebagai password hashing fungsi sebagai "berasal kunci" cukup panjang untuk menghindari "generic preimages" (penyerang hanya beruntung dan menemukan password yang menghasilkan output yang sama). Output lebih dari 100 bit atau jadi akan cukup. Memang, PBKDF2 dan scrypt yang KDF, tidak hashing password fungsi-dan NIST "menyetujui" dari PBKDF2 sebagai KDF, tidak secara eksplisit sebagai password hasher (tapi mungkin, dengan jumlah menit dari kemunafikan, untuk membaca NIST's prosa dalam cara yang tampaknya untuk mengatakan bahwa PBKDF2 baik untuk hashing password). Sebaliknya, bcrypt adalah benar-benar block cipher (sebagian besar password pengolahan adalah "key jadwal") yang kemudian digunakan dalam CTR mode untuk menghasilkan tiga blok (yaitu 192 bit) pseudo-random output, sehingga jenis fungsi hash. bcrypt dapat berubah menjadi KDF dengan sedikit operasi, dengan menggunakan cipher blok RKT mode untuk lebih blok. Tapi, seperti biasa, kami tidak bisa merekomendasikan buatan sendiri tersebut berubah. Untungnya, 192 bit yang sudah lebih dari cukup untuk sebagian besar tujuan (misalnya enkripsi simetris dengan GCM atau EAX hanya membutuhkan kunci 128-bit).
Miscellaneous Topik
Berapa banyak iterasi ?
Sebanyak mungkin ! Ini asin-dan-lambat hashing adalah sebuah arms race antara penyerang dan bek. Anda menggunakan banyak iterasi untuk membuat hashing password sulit untuk everybody. Untuk meningkatkan keamanan, anda harus mengatur nomor yang setinggi anda dapat mentolerir pada server anda, mengingat tugas-tugas yang server anda harus jika tidak memenuhi. Lebih tinggi lebih baik.
Tabrakan dan MD5
MD5 adalah broken: itu adalah komputasi mudah untuk menemukan banyak pasangan yang berbeda input yang hash dengan nilai yang sama. Ini disebut collisions. Namun, tabrakan tidak masalah untuk hashing password. Hashing Password yang membutuhkan fungsi hash untuk menjadi tahan terhadap preimages, tidak tabrakan. Tabrakan adalah tentang menemukan pasangan dari pesan-pesan yang memberikan output yang sama tanpa restriction_, sedangkan di hashing password penyerang harus menemukan pesan yang menghasilkan given output bahwa penyerang tidak bisa memilih. Ini sangat berbeda. Sejauh yang kami tahu, MD5 masih (hampir) sebagai kuat seperti itu pernah berkaitan dengan preimages (ada teoritis serangan yang masih sangat jauh di menggelikan mustahil untuk dijalankan dalam praktek). Yang real problem dengan MD5 seperti yang biasa digunakan dalam password hashing adalah bahwa hal itu sangat cepat, dan tawar. Namun, PBKDF2 digunakan dengan MD5 akan menjadi kuat. Anda masih harus menggunakan SHA-1 atau SHA-256 dengan PBKDF2, tapi untuk Public Relations. Orang-orang gugup ketika mereka mendengar "MD5".
Garam Generasi
Utama dan hanya titik dari garam adalah untuk menjadi seperti unique mungkin. Setiap kali nilai salt ini kembali anywhere, ini memiliki potensi untuk membantu penyerang. Misalnya, jika anda menggunakan pengguna name seperti garam, kemudian penyerang (atau beberapa berkolusi penyerang) bisa menemukan itu berguna untuk membangun tabel pelangi yang menyerang fungsi hashing password ketika garam "admin" (atau "root" atau "joe") karena akan ada beberapa, mungkin banyak situs di seluruh dunia yang akan memiliki seorang pengguna bernama "admin". Demikian pula, ketika pengguna mengubah password-nya, ia biasanya membuat nama-nya, yang mengarah ke garam digunakan kembali. Old password yang berharga target, karena pengguna memiliki kebiasaan menggunakan kembali password di beberapa tempat (yang's dikenal untuk menjadi ide yang buruk, dan diiklankan seperti itu, tapi mereka akan melakukannya meskipun demikian, karena itu membuat hidup mereka lebih mudah), dan juga karena orang-orang cenderung untuk menghasilkan password mereka "di urutan": jika anda belajar bahwa Bob's old password "SuperSecretPassword37", kemudian Bob's current password adalah mungkin "SuperSecretPassword38" atau "SuperSecretPassword39". The murah untuk mendapatkan keunikan adalah dengan menggunakan randomness. Jika anda menghasilkan garam sebagai urutan byte random dari cryptographically aman PRNG bahwa anda menawarkan sistem operasi (
/dev/urandom
,CryptGenRandom()
...) maka anda akan mendapatkan garam-nilai yang akan menjadi "unik dengan probabilitas yang cukup tinggi". 16 byte yang cukup sehingga anda tidak akan pernah melihat garam tabrakan dalam hidup anda, yang ini berlebihan tapi cukup sederhana. UUID adalah standar cara menghasilkan "unik" nilai-nilai. Perhatikan bahwa "versi 4" UUID hanya menggunakan keacakan (122 random bits), seperti yang dijelaskan di atas. Banyak kerangka kerja pemrograman menawarkan mudah untuk menggunakan fungsi-fungsi untuk menghasilkan UUID pada permintaan, dan mereka dapat digunakan sebagai garam.Garam Kerahasiaan
Garam tidak dimaksudkan untuk menjadi rahasia; jika tidak, kami akan memanggil mereka keys. Anda tidak need untuk membuat garam publik, tetapi jika anda harus membuat mereka publik (misalnya untuk mendukung client-side hashing), kemudian don't khawatir terlalu banyak tentang hal itu. Garam-garam yang ada untuk keunikan. Tegasnya, garam tidak lebih dari pemilihan tertentu fungsi hash dalam keluarga besar fungsi.
"Lada"
Kriptografer tidak pernah bisa membiarkan metafora saja; mereka must memperpanjang dengan analogi dan bad puns. "Membumbui" adalah tentang menggunakan rahasia garam, yaitu sebuah kunci. Jika anda menggunakan "lada" password hashing fungsi, kemudian anda beralih ke jenis yang sangat berbeda dari algoritma kriptografi; yaitu, anda komputasi Message Authentication Code di atas password. MAC kuncinya adalah anda "lada". Membumbui masuk akal jika anda dapat memiliki kunci rahasia yang penyerang tidak akan dapat dibaca. Ingat bahwa kita menggunakan password hashing karena kita menganggap bahwa seorang penyerang dapat mengambil salinan dari server database, atau mungkin dari seluruh disk_ dari server. Skenario akan menjadi server dengan dua disk di RAID 1. Salah satu disk gagal (papan elektronik goreng - ini banyak terjadi). Sysadmin menggantikan disk, cermin dibangun kembali, tidak ada data yang hilang karena sihir dari RAID 1. Sejak lama disk disfungsional, sysadmin tidak dapat dengan mudah menghapus isinya. Dia hanya membuang disk. Penyerang pencarian melalui kantong sampah, mengambil disk, menggantikan papan, dan lo! Dia memiliki sebuah gambar yang lengkap dari seluruh sistem server, termasuk database, konfigurasi file, binari, sistem operasi... monty penuh, seperti Inggris mengatakan. Untuk membumbui untuk menjadi benar-benar berlaku, anda harus berada dalam pengaturan khusus di mana ada sesuatu yang lebih dari sebuah PC dengan disk; anda perlu HSM. HSM yang sangat mahal, baik dalam hardware dan dalam operasional prosedur. Tapi dengan HSM, anda hanya dapat menggunakan rahasia "lada" dan proses password dengan sederhana HMAC (misalnya dengan SHA-1 atau SHA-256). Ini akan jauh lebih efisien dari bcrypt/PBKDF2/scrypt dan rumit mereka iterasi. Juga, penggunaan HSM akan terlihat sangat profesional ketika melakukan WebTrust audit.
Client-side hashing
Sejak hashing adalah (sengaja) mahal, itu bisa masuk akal, dalam client-server situasi, memanfaatkan CPU yang menghubungkan klien. Setelah semua, ketika 100 klien terhubung ke satu server, klien secara kolektif memiliki lebih banyak otot daripada server. Untuk melakukan client-side hashing, protokol komunikasi harus ditingkatkan untuk mendukung pengiriman garam kembali ke klien. Ini berarti tambahan round-trip, bila dibandingkan dengan klien sederhana-mengirim-password-server protokol. Hal ini mungkin atau mungkin tidak akan mudah untuk menambahkan untuk kasus spesifik anda. Client-side hashing adalah sulit dalam konteks Web karena klien menggunakan Javascript, yang cukup anemia untuk CPU-tugas intensif. Dalam konteks SRP, password hashing selalu terjadi pada sisi klien.
Kesimpulan
Gunakan bcrypt. PBKDF2 tidak buruk juga. Jika anda menggunakan scrypt anda akan menjadi "sedikit early adopter" dengan risiko yang tersirat oleh pernyataan ini, tetapi itu akan menjadi langkah yang baik untuk kemajuan ilmiah ("crash dummy" adalah sebuah profesi yang sangat terhormat).
Untuk menyimpan password hash, anda perlu sebuah algoritma yang cukup lambat bahwa serangan brute-force tidak layak. Pengasinan password akan membantu melawan pelangi serangan, tetapi tidak terhadap serangan brute-force. Untuk menyimpan hash password, anda perlu menggunakan sebuah algoritma yang dirancang khusus untuk tujuan ini; seperti:
scrypt
baru tapi menarik karena tidak hanya menggunakan variabel faktor pekerjaan tapi juga memori-keras fungsi. Hal ini secara dramatis meningkatkan biaya dari serangan brute force, karena keduanya berjalan-waktu dan persyaratan memori meningkat.
Password disimpan dalam database sebagai hash nilai-nilai yang dapat dipulihkan baik melalui brute-force perhitungan hash atau melalui menggunakan tabel pelangi (yang spesifik untuk algoritma yang digunakan).
Pelangi meja ini dibuat sebagai rangkaian pra-dihitung nilai-nilai yang baik untuk file kamus atau lebih sering setiap kombinasi yang diberikan set karakter [a-z, A-Z, 0-9] menjadi contoh umum.
Pada dasarnya mereka dapat mempercepat cracking password dengan membiarkan nilai hash yang akan dicari dalam table daripada membutuhkan penyerang untuk membuat hash untuk password masing-masing. Tabel pelangi untuk umum algoritma sandi (misalnya, NTLM, MD5, dll) dapat ditemukan secara online, sehingga cukup mudah untuk mendapatkan akses ke volume yang besar dari mereka.
Ada sejumlah cara untuk meningkatkan keamanan dari hash yang disimpan dalam database.
Pertama adalah dengan menggunakan per pengguna garam nilai, nilai ini disimpan dalam database bersama dengan hash password. Ini isn't dimaksudkan untuk menjadi rahasia tapi digunakan untuk memperlambat brute force proses dan untuk membuat tabel pelangi praktis untuk digunakan.
Add-on lain yang saya've melihat ini adalah untuk juga menambahkan dalam apa yang disebut merica nilai. Ini hanyalah sebuah string acak tapi itu sama untuk semua pengguna dan disimpan dengan kode aplikasi sebagai lawan dalam database. teori di sini adalah bahwa dalam beberapa keadaan database dapat dikompromikan tapi aplikasi kode ini tidak, dan dalam kasus-kasus ini bisa meningkatkan keamanan. Itu tidak, bagaimanapun, memperkenalkan masalah jika ada beberapa aplikasi yang menggunakan password yang sama database.
Ketiga sarana untuk membantu meningkatkan keamanan password adalah dengan menggunakan memperlambat fungsi password, ini tidak't memiliki dampak besar pada pengguna individu, tetapi secara besar-besaran akan memperlambat penyerang di cracking password yang diambil dari database. Beberapa informasi lebih lanjut tentang pendekatan ini tersedia di sini
Orang lain di sini telah menunjukkan bahwa serangan brute force harus membela melawan via garam, meskipun MYSQL masih belum't tahu itu. Pentingnya iterasi juga telah mencatat, dan telah dikenal sejak mani makalah tentang Unix crypt pada tahun 1978 oleh Robert Morris dan Ken Thompson. Tapi banyak orang (dan pengembang juga, seperti Django!) jelas masih berpikir brute force harus mengambil waktu yang cukup lama atau cukup mahal. Tidak benar! Moore's hukum dan cloud computing telah terjebak dengan kami. Untuk crack password alfanumerik panjang 8 ((26+26+10)^8 = 62^8 = 218,340,105,584,896 = 218 triliun kombinasi) pada desktop modern mesin ini memakan waktu 5 hari, atau 1 jam jika anda menyewa sekelompok Amazon node komputasi (Berapa lama waktu yang dibutuhkan untuk benar-benar menghasilkan tabel pelangi? - ITU Security) Update: bitcoin hashing kapasitas Yang paling kuat yang diselenggarakan hashing kemampuan di planet (termasuk mungkin diklasifikasikan sistem) adalah bitcoin mining network. Saat ini adalah melakukan SHA-256 hash pada agregat tingkat di atas 11 Thash/s, yaitu 11 10^12 hash/s (pada tahun 2016 yang 1700000 Thash/s - lihat update 4 di atas), dan tingkat telah meningkat dengan cepat baru-baru ini (grafik). Penambang sedang bekerja untuk mendapatkan sekitar $700.000 per minggu pertambangan hasil pada harga saat ini $14 per bitcoin (BTC) (grafik), dan tingkat 50 BTC yang dihasilkan setiap 10 menit. Populer perangkat keras hari-hari ini termasuk Radeon HD 5970 GPU, yang masing-masing memiliki total 3200 stream prosesor dan dapat melakukan sekitar 800 Mhash/s. Hal ini juga hemat dalam konsumsi daya di sekitar 2.3 Mhash/Joule. Lihat Bitcoin mining hardware comparison untuk lebih banyak pilihan. Ternyata bahwa GPU node di Amazon's EC2 menggunakan Nvidia Tesla Gpu yang kurang efisien pada hashing, dan mereka node aren't biaya yang efektif untuk pertambangan di hari ini's harga. Ini adalah sekitar dua kali kapasitas dari satu 5.5 Thash/s perkiraan untuk hashing power of the world's top 500 superkomputer dikombinasikan, meskipun tentu saja superkomputer biasanya dirancang untuk kinerja floating point, tidak hashing. Seperti yang ekstrim saat ini kasus, jika ini hashing kapasitas diarahkan untuk mencoba untuk memecahkan password, misalnya, setelah kecelakaan di harga bitcoin, itu akan menakutkan terhadap non-iterasi algoritma sandi. 8 karakter password menggunakan yang benar-benar acak bermacam-macam semua 94 pencetakan karakter akan jatuh dalam waktu kurang dari 10 menit.(94^8 / (11 10^12 60) = 9.2). 10 karakter password yang akan memakan waktu kurang dari 57 hari (94^10 / (11 10^12 3600 24) = 56.7). 10-karakter upper-lower case password alfanumerik (26+26+10 = 62 mungkin karakter) akan memakan waktu kurang dari satu hari (62^10 / (11 10^12 3600 24) = 0.88) bahkan jika juga acak. Tapi jika programmer hanya digunakan misalnya jumlah iterasi dari 2000 sebagai Thomas menunjukkan, baik 10-karakter password yang akan berlangsung bertahun-tahun. Meskipun 8 karakter password akan mudah retak, dalam 13 hari (2000 94^8 / 11 10^12 / 3600 / 24 = 12.8 hari). Lihat juga:
Password harus selalu diacak, tapi itu tidak berarti bahwa tidak ada kemungkinan untuk bruteforce-serangan. Langkah-langkah tambahan harus diterapkan mengenai penyimpanan dan mengelola pengguna dan kata sandi. Saya sangat merekomendasikan artikel ini dari Surya Desainer tentang topik ini: http://php-security.org/2010/05/26/mops-submission-10-how-to-manage-a-php-applications-users-and-passwords/index.html.
Password harus selalu menjadi asin dan membentang sebelum menyimpannya. Pada dasarnya hal ini melibatkan penambahan atau mengawali beberapa teks untuk hashing password dan hasil beberapa kali. Adapun hash algos apa-apa atas dan di atas MD5 dan SHA-1 saat ini dianjurkan - pergi untuk SHA 256 atau 512 (lihat http://www.schneier.com/blog/archives/2009/06/ever_better_cry.html)
Baik algoritma hashing password harus memiliki garam dan sesuatu untuk membuat perhitungan password mahal (biasanya jumlah iterasi).
Terbaik, dan yang paling umum, metode ini adalah PBKDF2. Meskipun tidak sempurna, ini harus menjadi dasar untuk semua orang:
I'd kedua rekomendasi untuk PBKDF2. It's bukan yang paling komputasi mahal, tetapi memiliki tepat standar untuk referensi selama pelaksanaan, dan's diterima.
https://tools.ietf.org/html/rfc2898
I'd benar-benar merekomendasikan membaca Colin Percival's kertas di scrypt, meskipun. Dia melakukan pekerjaan yang baik yang menggambarkan masalah dalam bermain di sini. Dugaan saya adalah scrypt akan terlihat lebih baik dan lebih baik dengan waktu.
http://www.tarsnap.com/scrypt.html
Memiliki implementatif standar tidak apa-apa, dengan cara - ada perbedaan antara algoritma yang dijelaskan dalam makalah dan referensi implementasi di kedua bcrypt dan scrypt, jika ingatanku.
Tergantung pada algoritma yang anda gunakan jawabannya mungkin tidak.
Pertama anda harus Garam mereka, ini pada dasarnya berarti menambahkan atau mengawali beberapa teks untuk password.
Maka anda harus menggunakan kuat algoritma (md5 doesn't dipotong)
Hal ini menarik untuk dicatat bahwa meskipun bcrypt dan scrypt semua solusi yang baik untuk password, dengan kebaikan untuk yang terakhir, scrypt tampaknya rentan terhadap cache-waktu serangan. Seperti yang disarankan berikut ini: http://eprint.iacr.org/2013/525 Catena akan aman terhadap hal ini, bersama dengan dibuktikan keamanan dan beberapa fitur bagus lainnya.
bcrypt dikatakan menjadi lebih lambat pada Gpu, yang membuat brute-forcing lebih lambat. Namun, dengan semakin berkembang hardware komputer, kita tidak boleh hanya bergantung pada kesulitan pelaksanaan tertentu algoritma hashing pada hardware tertentu.
Sebaliknya, anda bisa sewenang-wenang meningkatkan biaya untuk bruteforcing hash dengan menggunakan "variabel pekerjaan/biaya faktor" (kadang-kadang juga disebut "putaran") yang beberapa fungsi hash dukungan. Di antara mereka adalah bcrypt dan SHA-512.
Glibc's crypt()
fungsi memungkinkan spesifikasi dari putaran untuk beberapa algoritma hash. Misalnya, faktor biaya dari 100000
untuk SHA-512 yang membuat generasi (dan oleh karena itu brute-forcing) hash sekitar 4 kali lebih lambat dari faktor biaya 08
untuk bcrypt. Hal ini dapat dikonfirmasi dengan menggunakan hash pemecahan program seperti hashcat.
Jika anda menganggap bahwa di beberapa titik sandi hash dan garam akan dicuri dan penyerang akan menggunakan ASIC hardware untuk bruteforce mereka, anda hanya meningkatkan faktor pekerjaan untuk tetap membuatnya terlalu mahal bagi mereka, sementara tidak memberatkan server anda's CPU dengan teratur otentikasi pengguna.
Pentingnya panjang dan random password berlaku demikian.
Saya hanya menulis blog post tentang rincian.
tsk tsk, Untuk mencoba untuk mengamankan sistem melalui lambat enkripsi adalah orang bodoh's tugas.
Misalnya, let's mengatakan sebaliknya, kita memiliki hash, dan kita ingin memperoleh passwordnya (dan garam jika ada).
Bahkan jika kita ingin menjalankan miliaran hash per detik, kita perlu cara untuk mencocokkan nilai.
Misalnya, let's mengatakan nilai berikutnya:
GARAM:IT_ISASALT NILAI:123456 dan itu adalah hash: 7D371ADDB8862FD3B8320020B0C6B52BEE716A8204CA18B03C9A6B4686EEB610
Jadi kita ingin mengubah hash-> GARAM+NILAI.
Salah satu cara untuk mencapai hal ini, it's untuk mengenkripsi nilai dan coba bandingkan jika bagian dari nilai yang ada di beberapa kamus.
Misalnya, kita diuji kombinasi dan kami menemukan:
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434dKUDA ("kuda" adalah sebuah kata yang ada dalam kamus kami).
Itu nilai yang tepat?. Kami don't tahu, tapi itu bisa, jadi kita harus menyimpan kombinasi ini dan mencoba dengan yang lain. It's proses yang lambat dan membutuhkan banyak memori. Tetapi bahkan jika mungkin, kita bisa menemukan banyak nilai-nilai palsu. Jadi, kita bisa mengurangi pertandingan dari 2^256 kombinasi 2^100 atau lebih kombinasi. Untuk ini, kita membutuhkan beberapa cara untuk menemukan pertandingan yang benar. Jika GARAM tidak sepele, maka tugas ini bisa memakan banyak waktu dan sumber daya, dan peluang keberhasilan yang masih lambat.
Sekarang, let's mengatakan kita bisa menghasilkan hash baru (misalnya, kita membuat sebuah akun palsu), sehingga kita tahu nilai dan hash (tapi garam). Ini menyederhanakan banyak operasi, karena menemukan sebuah pertandingan adalah sama dengan menemukan teks yang berakhir dengan nilai (contoh: 123456). Tapi bagaimana jika garam tidak dihasilkan sebagai GARAM+NILAI tapi SALT1+NILAI+SALT2 atau jika GARAM+VALUE2 mana VALUE2 adalah nilai yang dimodifikasi dengan beberapa algoritma yang kita don't tahu.
Sekarang, let's mengatakan kami hash yang dihasilkan sebagai berikut:
hash256(GARAM+hash256(GARAM+NILAI))
Jadi, kesimpulannya:
Saya menggunakan SHA1 di sini
def __encrypt(self, plaintext, salt=""):
"""returns the SHA1 hexdigest of a plaintext and salt"""
phrase = hashlib.sha1()
phrase.update("%s--%s" % (plaintext, salt))
return phrase.hexdigest()
def set_password(self, new_password):
"""sets the user's crypted_password"""
#from datetime import datetime, timedelta
import datetime
if not self.salt:
self.salt = self.__encrypt(str(datetime.datetime.now()))
self.crypted_password = self.__encrypt(new_password, self.salt)
def check_password(self, plaintext):
return self.__encrypt(plaintext, self.salt) == self.crypted_password
Daripada pengasinan password seperti ini aku akan seperti itu algoritma berubah sehingga tidak't membutuhkan garam dan masih won't hash input yang sama dua kali dengan nilai yang sama.