Ketika saya ingin menempatkan sistem login, saya selalu membandingkan MD5 dari kata sandi yang diberikan dengan nilainya di tabel pengguna di sisi server.
Namun, seorang teman saya mengatakan kepada saya bahwa kata sandi "jelas" dapat diendus oleh perangkat lunak jaringan.
Jadi pertanyaan saya adalah: apakah itu ide yang bagus untuk hash password di sisi klien Apakah lebih baik daripada hashing di sisi server?
passwords
client-side
hash
Zakaria
sumber
sumber
Jawaban:
Pada dasarnya, temanmu benar. Tetapi hanya dengan hashing kata sandi di sisi klien hanya lebih baik daripada mengirimkannya sebagai teks biasa ke server. Seseorang, yang dapat mendengarkan kata sandi teks biasa Anda tentu juga dapat mendengarkan kata sandi hash, dan menggunakan hash yang ditangkap ini sendiri untuk mengotentikasi terhadap server Anda.
Untuk masalah ini, protokol otentikasi yang lebih aman biasanya melompati sejumlah rintangan untuk memastikan, bahwa serangan replay seperti itu tidak dapat bekerja, biasanya, dengan memungkinkan klien untuk memilih banyak bit acak, yang diacak bersama dengan kata sandi , dan juga dikirimkan secara jelas ke server.
Di server:
Pada klien:
Karena server mengetahui informasi acaknya sendiri serta bit acak klien (ia mendapatkannya sebagai teks yang jelas), pada dasarnya ia dapat melakukan transformasi yang sama. Protokol ini memastikan, bahwa tidak ada yang mendengarkan dalam percakapan ini dapat menggunakan informasi nanti untuk mengotentikasi secara salah menggunakan informasi yang direkam (kecuali algoritma yang sangat lemah digunakan ...), selama kedua belah pihak menghasilkan "bit noise" yang berbeda setiap kali, berjabat tangan dilakukan.
Sunting Semua ini rawan kesalahan dan membosankan dan agak sulit untuk diperbaiki (baca: aman). Jika memungkinkan, pertimbangkan untuk menggunakan implementasi protokol otentikasi yang telah ditulis oleh orang yang berpengetahuan (tidak seperti saya! Di atas hanya dari memori buku yang saya baca beberapa waktu lalu.) Anda benar-benar tidak ingin menulis ini sendiri biasanya.
sumber
Pertama-tama, ini TIDAK meningkatkan keamanan aplikasi Anda (dengan asumsi itu adalah aplikasi web).
Gunakan SSL (Atau sebenarnya TLS, yang biasa disebut SSL), ini tidak terlalu mahal (Ukur waktu yang Anda gunakan untuk menemukan cara di sekitarnya dan gandakan dengan upah minimum, membeli sertifikat menang hampir selalu).
Mengapa ini sederhana? TLS memecahkan masalah (ketika digunakan dengan sertifikat yang dibeli, tidak ditandatangani sendiri) yang cukup besar dalam kriptografi: Bagaimana saya tahu server yang saya ajak bicara adalah server yang saya pikir saya ajak bicara? Sertifikat TLS adalah cara untuk mengatakan: "Saya, otoritas sertifikat, dipercaya oleh browser Anda, menyatakan bahwa situs web di [url] memiliki kunci publik ini, dengan kunci pribadi yang sesuai, yang (kunci pribadi) yang hanya diketahui oleh server, lihat Saya menandatangani tanda tangan saya di seluruh dokumen, jika ada yang mengubahnya, Anda dapat melihat ".
Tanpa TLS, enkripsi apa pun menjadi tidak ada gunanya, karena jika saya duduk di sebelah Anda dalam sebuah coffeeshop, saya dapat membuat laptop / smartphone Anda berpikir saya adalah server dan MiTM (Man in The Middle) Anda. Dengan TLS, laptop / smartphone Anda akan meneriakkan "SAMBUNGAN TIDAK TERPERCAYA", karena saya tidak memiliki otoritas sertifikat yang menandatangani sertifikat yang cocok dengan situs Anda. (Enkripsi vs. Otentikasi).
Penafian: pengguna cenderung mengklik kanan melalui peringatan ini: "Koneksi tidak tepercaya? Apa? Saya hanya ingin gambar anak kucing saya! Tambahkan Pengecualian Klik Konfirmasi Klik YAY! Anak kucing!"
Namun, jika Anda benar-benar tidak ingin membeli sertifikat, masih DO mengimplementasikan hash javascript sisi klien (dan menggunakan perpustakaan standford (SJCL) untuk itu, JANGAN PERNAH MELAKUKAN CRYPTO DIRI SENDIRI ).
Mengapa? Penggunaan kembali kata sandi! Saya dapat mencuri cookie sesi Anda (yang memungkinkan saya untuk berpura-pura ke server Anda bahwa saya adalah Anda) tanpa HTTPS dengan mudah (lihat firesheep). Namun jika Anda menambahkan javascript ke halaman login Anda yang, sebelum mengirim, hash kata sandi Anda (gunakan SHA256, atau bahkan lebih baik, gunakan SHA256, kirim mereka kunci publik yang Anda buat dan kemudian enkripsi hash password dengan itu, Anda tidak dapat menggunakan garam dengan ini), dan kemudian mengirimkan kata sandi hash / terenkripsi ke server. REHASH hash di server Anda dengan garam dan bandingkan dengan apa yang disimpan dalam database Anda (simpan kata sandi seperti ini:
(simpan garam sebagai plaintext dalam database juga)). Dan kirim kata sandi Anda seperti ini:
dan periksa kata sandi Anda seperti ini:
Karena, JIKA seseorang mengendus klien Anda, mereka akan dapat masuk sebagai klien Anda (pembajakan sesi) tetapi mereka TIDAK AKAN PERNAH melihat kata sandi plaintext (kecuali jika mereka mengubah javascript Anda, namun, peretas starbucks mungkin tidak akan tahu caranya / tertarik) dalam hal ini.) Jadi mereka akan mendapatkan akses ke aplikasi web Anda, tetapi tidak ke email / facebook / etc mereka. (di mana pengguna Anda kemungkinan akan menggunakan kata sandi yang sama). (Alamat email akan menjadi nama login mereka atau akan ditemukan di profil / pengaturan mereka di aplikasi web Anda).
sumber
Anda mungkin OK untuk tidak khawatir tentang ini - seperti Dirk menyebutkan bahkan jika Anda hash kata sandi pengguna jahat dapat berada di jaringan dan melihat hash dikirim, dan cukup mengirim hash yang sama sendiri.
Ini sedikit lebih baik, karena mencegah pengguna jahat mengetahui apa kata sandinya, tetapi karena mereka masih bisa masuk (atau berpotensi merekonstruksi kata sandi asli ), itu tidak membantu.
Secara umum, jika Anda khawatir tentang keamanan kata sandi dan data pengguna Anda (dan memang seharusnya begitu!), Anda ingin menggunakan server SSL yang aman. Jika ini bukan masalah bagi Anda untuk alasan apa pun Anda mungkin juga tidak repot dengan hashing; itu hanya keamanan melalui ketidakjelasan .
Sunting Agustus 2014: Google mendorong semakin banyak situs web untuk beralih ke HTTPS di mana-mana , karena mengamankan komunikasi itu sendiri adalah satu-satunya cara untuk mencegah serangan mengendus jaringan. Upaya mengaburkan data yang dikirimkan hanya akan menghalangi, tidak berhenti, penyerang yang berdedikasi, dan dapat memberi pengembang rasa aman palsu yang berbahaya.
sumber
x
kata sandi pengguna dan mengakses satu layanan. Jika Anda mempertimbangkan efek kolektif, saya akan mengatakan itu "jauh lebih baik"; karena mencegah membangun database pencarian besar dari kata sandi yang digunakan untuk memaksa hash asin di berbagai layanan. IMO. Lihat apa yang dilakukan AWS Cognito di klien untuk referensi.Sebenarnya saya tidak setuju bahwa hashing sisi klien lebih aman dalam kasus ini. Saya pikir itu kurang aman.
Inti menyimpan hash kata sandi di basis data Anda sebagai lawan dari kata sandi asli (atau bahkan kata sandi terenkripsi) adalah bahwa secara matematis tidak mungkin untuk mendapatkan kata sandi asli dari hash (walaupun secara teori dimungkinkan untuk mendapatkan tabrakan masukan hash, kesulitan yang tergantung pada kekuatan keamanan dari algoritma hashing). Vektor kemungkinan serangan di sini adalah bahwa jika penyerang potensial entah bagaimana membahayakan basis data penyimpanan kata sandi Anda, ia masih tidak akan dapat memperoleh kata sandi asli dari pengguna Anda.
Jika mekanisme otentikasi Anda mengirim hash kata sandi, maka dalam skenario pelanggaran keamanan ini, penyerang tidak perlu mengetahui kata sandi asli - mereka hanya mengirim hash yang mereka miliki dan hei presto, mereka memiliki akses ke akun pengguna tertentu, dan dengan ekstensi, seluruh sistem Anda. Ini benar-benar mengalahkan titik menyimpan kata sandi hash di tempat pertama!
Cara yang benar-benar aman untuk melakukannya adalah dengan mengirimkan klien kunci publik satu kali bagi mereka untuk mengenkripsi kata sandi, kemudian Anda mendekripsi dan hash kembali di sisi server.
Ngomong-ngomong, pertanyaan semacam ini mungkin akan mendapatkan lebih banyak tanggapan pakar tentang Keamanan StackExchange.
sumber
Perhatikan bahwa menjaga keamanan kata sandi dari pihak ketiga tidak cukup.
Segera setelah privasi terlibat (dan kapan pun tidak, hari ini?), Anda tidak ingin mengetahui kata sandi. Anda tidak dapat menyalahgunakan atau membocorkan apa yang tidak Anda miliki , sehingga Anda dan klien Anda dapat tidur lebih nyenyak jika Anda tidak pernah melihat kata sandi yang jelas.
Oleh karena itu, hashing / mengenkripsi sisi klien masuk akal.
sumber
x
pengguna padan
layanan yang hanya mengenkripsi di server. Jika setiap layanan secara unik melakukan hash kata sandi sebelum meninggalkan klien, basis data besar kata sandi lintas-layanan menjadi jauh lebih kecil. Periksa lalu lintas masuk AWS Anda, lihat apa yang mereka lakukan. Itu kemungkinan Watson tersayang.Itu tergantung, Anda dapat menggunakan hashing sisi klien, tetapi garam sisi server tidak akan mungkin.
lihat tautan Enkripsi kata sandi di sisi klien
sumber
Saya telah melakukan banyak pekerjaan pada ini baru-baru ini, IRL ada dua masalah dengan hash / enkripsi simetris sisi klien dengan benar-benar membunuh ide: 1. Anda harus mendapatkan garam kembali ke server SOMEHOW ... dan untuk mengenkripsi di sisi klien Anda memerlukan kata sandi ... yang mengalahkan tujuan. 2. Anda mengekspos implementasi hashing Anda (bukan kesepakatan BESAR karena sebagian besar situs menggunakan salah satu dari 3 atau 4 alga hashing) yang membuat serangan lebih mudah (karena hanya perlu mencoba satu daripada n).
Yang akhirnya saya tuju adalah enkripsi asimetris pada klien menggunakan OpenPGP.js atau serupa ... Ini bergantung pada kunci yang diimpor atau sisi klien yang dihasilkan pada klien dan server yang mengirimkan kunci publik itu. Hanya kunci publik klien yang dapat dikirim kembali ke server. Ini melindungi terhadap serangan MIM dan seaman perangkat (Saat ini saya menyimpan kunci pribadi klien secara default di localStore, ini demo).
Keuntungan utama dari ini adalah bahwa saya tidak pernah memiliki data pengguna disimpan / bahkan dalam memori tidak dienkripsi di server / penyimpanan data saya (dan kunci pribadi server saya secara fisik terpisah)
Dasar dari ini adalah untuk memberikan orang cara untuk berkomunikasi dengan aman di mana HTTPS dibatasi (misalnya, Iran / Korea Utara ...) dan juga hanya eksperimen yang menyenangkan.
Saya JAUH dari yang pertama memikirkan hal ini, http://www.mailvelope.com/ menggunakan ini
sumber
Jika seseorang dapat melihat data masuk dan keluar di koneksi Anda maka otentikasi tidak akan menyelamatkan Anda. Sebaliknya saya akan melakukan hal berikut untuk hal-hal super rahasia.
Kata sandi diucapkan di sisi klien sebelum dikirim ke server. (Server menyimpan nilai hash dan salin lain dari hash yang dikirim dari browser).
Jadi serangan orang tengah dapat memungkinkan mereka untuk mengirim nilai hash yang sama untuk login seperti mereka, tetapi kata sandi pengguna tidak akan diketahui. Ini akan menghentikan mereka mencoba layanan lain dengan kredensial yang sama untuk masuk ke tempat lain.
Data pengguna juga dienkripsi di sisi browser.
Ah, jadi serangan perantara akan mendapatkan data terenkripsi, tetapi tidak akan dapat mendekripsi tanpa kata sandi yang sebenarnya digunakan untuk login. (kata sandi pengguna yang disimpan di DOM di browser saat mereka masuk). Jadi pengguna sebenarnya akan melihat konten yang didekripsi tetapi perantara tidak bisa. Ini juga berarti NSA atau agensi lain tidak akan dapat meminta Anda / perusahaan / penyedia hosting untuk mendekripsi data ini karena tidak mungkin bagi mereka untuk melakukannya juga.
Beberapa contoh kecil dari kedua metode ini ada di blog saya http://glynrob.com/javascript/client-side-hashing-and-encryption/
sumber
Baru-baru ini baik GitHub dan Twitter mengumumkan kata sandi itu di mana disimpan dalam log internal. Saya pernah mengalami hal ini secara tidak sengaja dalam laporan bug dan log lain yang menemukan jalannya ke splunk, dll. Untuk twitter jika kata sandi Trump ada di log, itu bisa menjadi masalah besar bagi admin untuk "melihat", karena situs lain mungkin tidak sebanyak masalah besar karena administrator tidak akan banyak menggunakan untuk itu. Apa pun admin, kami tidak suka melihat kata sandi.
Jadi pertanyaannya adalah benar-benar jika hashing harus terjadi pada sisi klien untuk keamanan, tetapi bagaimana kita bisa melindungi kata sandi sebelum akhirnya di-hash dan dibandingkan oleh sisi server sehingga tidak bisa login entah bagaimana.
Enkripsi bukanlah ide yang buruk karena pengembang setidaknya harus melewati beberapa rintangan, dan jika Anda menemukan kata sandi masuk ke log, Anda dapat mengubah kunci enkripsi, menghancurkan yang asli, dan data menjadi tidak berguna. Lebih baik lagi memutar tombol setiap malam dan itu bisa mengurangi jendela sangat.
Anda juga bisa hash hash dalam catatan pengguna Anda. Kata sandi yang bocor akan menjadi kata sandi teks biasa. Server akan menyimpan versi hash. Tentu hash menjadi kata sandi, tetapi kecuali jika Anda memiliki memori fotografis, Anda tidak akan mengingat 60 karakter bcyrpt. Garam dengan nama pengguna. Jika Anda bisa mengumpulkan sesuatu tentang pengguna selama proses login (sambil tidak mengungkapkan bahwa catatan pengguna ada), Anda dapat menambahkan garam dengan itu juga menciptakan hash yang lebih kuat yang tidak dapat dibagi antara situs. Tidak ada orang di tengah yang bisa memotong dan menempel hash yang ditangkap di antara situs.
Gabungkan dengan cookie yang tidak dikirimkan kembali ke server dan Anda mungkin menemukan sesuatu. Pada permintaan pertama, kirimkan cookie ke klien dengan kunci, lalu pastikan cookie itu tidak kembali ke layanan login sehingga kecil kemungkinannya untuk dicatat. Simpan kunci di toko sesi, dan kemudian hapus segera setelah login terjadi atau ketika sesi berakhir ... ini mengharuskan Anda JWT guys, tetapi mungkin hanya menggunakan layanan nosql untuk itu.
Jadi, seorang admin menemukan salah satu dari kata sandi hash dan terenkripsi ini dalam splunk atau alat pelaporan bug. Seharusnya tidak berguna bagi mereka karena mereka tidak dapat menemukan kunci enkripsi lagi, dan bahkan jika mereka melakukannya, mereka harus memaksa hash. Selain itu, pengguna akhir tidak mengirim plaintext apa pun di sepanjang baris sehingga siapa pun di tengah setidaknya memiliki waktu yang lebih sulit dan Anda tidak bisa langsung masuk ke situs lain dan masuk.
sumber
Pertimbangkan ini: -
Klien mengirimkan permintaan ke server "Saya memiliki kata sandi untuk memvalidasi".
Server mengirim klien string acak satu kali saja. R $
Klien menyematkan kata sandi pengguna dalam string ini (berdasarkan pada setiap (variabel) aturan yang ingin Anda terapkan).
Klien mengirimkan string ke server dan jika kata sandi OK, server mencatat pengguna.
Jika server menerima permintaan login lain menggunakan R $, pengguna keluar dan akun dibekukan, sedang menunggu penyelidikan.
Jelas sekali semua tindakan pengamanan (normal) lainnya akan dilakukan.
sumber
Gagasan hashing sisi klien ini adalah untuk melindungi pengguna, bukan situs Anda. Seperti yang telah disebutkan berulang kali, teks biasa atau kata sandi hash keduanya memiliki akses ke situs Anda secara merata. Anda tidak mendapatkan manfaat keamanan.
Tetapi pengguna Anda yang sebenarnya, teks biasa, kata sandi seharusnya hanya diketahui oleh mereka. Mengetahui apa yang mereka pilih sebagai kata sandi adalah informasi yang dapat digunakan untuk melawan mereka di situs dan sistem lain. Anda menjadi situs yang berfokus pada pelanggan dengan melindungi mereka dari pilihan kata sandi yang ditemukan oleh server dev atau oleh pihak ketiga.
sumber