Saya perhatikan bahwa sebagian besar situs mengirim kata sandi sebagai teks biasa melalui HTTPS ke server. Apakah ada keuntungan jika saya mengirimkan hash kata sandi ke server? Apakah lebih aman?
Saya perhatikan bahwa sebagian besar situs mengirim kata sandi sebagai teks biasa melalui HTTPS ke server. Apakah ada keuntungan jika saya mengirimkan hash kata sandi ke server? Apakah lebih aman?
Jawaban:
Ini pertanyaan lama, tapi saya merasa perlu memberikan pendapat saya tentang masalah penting ini. Ada banyak informasi yang salah di sini
OP tidak pernah menyebutkan mengirim kata sandi dengan jelas melalui HTTP - hanya HTTPS, namun banyak yang tampaknya menanggapi pertanyaan mengirim kata sandi melalui HTTP untuk beberapa alasan. Yang mengatakan:
Saya percaya kata sandi tidak boleh disimpan (apalagi dikirim) dalam teks biasa. Artinya tidak disimpan di disk, atau bahkan di memori.
Orang-orang yang menanggapi di sini tampaknya berpikir HTTPS adalah peluru perak, padahal sebenarnya bukan. Ini tentu sangat membantu bagaimanapun, dan harus digunakan dalam setiap sesi yang diautentikasi.
Sebenarnya tidak perlu mengetahui apa itu kata sandi asli. Semua yang diperlukan adalah cara yang andal untuk menghasilkan (dan menghasilkan kembali yang andal) sebuah "kunci" otentikasi berdasarkan teks asli yang dipilih oleh pengguna. Dalam dunia yang ideal, teks ini harus segera menghasilkan "kunci" dengan mencirikannya menggunakan garam yang tidak dapat diubah. Salt ini harus unik untuk kredensial pengguna yang dibuat. "Kunci" ini akan menjadi apa yang digunakan sistem Anda sebagai kata sandi. Dengan cara ini jika sistem Anda pernah disusupi di masa mendatang, kredensial ini hanya akan berguna untuk organisasi Anda sendiri, dan tidak di tempat lain di mana pengguna bermalas-malasan dan menggunakan sandi yang sama.
Jadi kami punya kuncinya. Sekarang kita perlu membersihkan semua jejak kata sandi di perangkat klien.
Selanjutnya kita perlu mendapatkan kunci itu ke sistem Anda. Anda tidak boleh mengirimkan kunci atau sandi "dengan jelas". Bahkan tidak melalui HTTPS. HTTPS tidak bisa ditembus. Faktanya, banyak organisasi dapat menjadi MITM tepercaya - bukan dari perspektif serangan, tetapi untuk melakukan inspeksi pada lalu lintas untuk menerapkan kebijakan keamanan mereka sendiri. Ini melemahkan HTTPS, dan ini bukan satu-satunya cara itu terjadi (seperti pengalihan ke serangan HTTP MITM misalnya). Jangan pernah menganggapnya aman.
Untuk menyiasati ini, kami mencirikan kunci dengan nonce sekali. Nonce ini unik untuk setiap pengiriman kunci ke sistem Anda - bahkan untuk kredensial yang sama selama sesi yang sama jika Anda perlu mengirimnya beberapa kali. Anda dapat membalikkan nonce ini setelah masuk di sistem Anda sendiri untuk memulihkan kunci otentikasi, dan mengautentikasi permintaan.
Pada titik ini saya akan melakukan hash secara permanen untuk terakhir kalinya sebelum disimpan secara permanen di sistem Anda sendiri. Dengan cara itu Anda dapat membagikan garam kredensial dengan organisasi mitra untuk tujuan SSO dan sejenisnya, sambil dapat membuktikan bahwa organisasi Anda sendiri tidak dapat meniru pengguna. Bagian terbaik dari pendekatan ini adalah Anda tidak akan pernah membagikan apa pun yang dibuat oleh pengguna tanpa izin mereka.
Lakukan lebih banyak penelitian, karena ada lebih banyak daripada yang telah saya ungkapkan, tetapi jika Anda ingin memberikan keamanan sejati kepada pengguna Anda, saya pikir metode ini saat ini merupakan respons paling lengkap di sini.
TL; DR:
Gunakan HTTPS. Mencirikan kata sandi secara aman, tidak dapat diubah, dengan salt unik per kata sandi. Lakukan ini pada klien - jangan mengirimkan kata sandi mereka yang sebenarnya. Mengirimkan kata sandi asli pengguna ke server Anda tidak pernah "OK" atau "Baik". Bersihkan semua jejak kata sandi asli. Gunakan nonce terlepas dari HTTP / HTTPS. Ini jauh lebih aman di banyak tingkatan. (Jawaban untuk OP).
Karena ini melalui HTTPS, tidak masalah untuk mengirim kata sandi tanpa hashing (melalui HTTPS itu bukan teks biasa). Selain itu, jika aplikasi Anda bergantung pada HTTPS untuk menjaga kontennya tetap aman, maka tidak ada gunanya meng-hash kata sandi sebelum mengirimkannya melalui HTTPS (yaitu jika penyerang dapat membatalkan enkripsi data pada kabel, Anda akan disekrup)
Tidak, sebenarnya ini adalah kerentanan. Jika penyerang dapat memperoleh hash dari database, maka ia dapat menggunakannya untuk mengautentikasi tanpa perlu membobolnya. Dalam situasi apa pun pengguna atau penyerang tidak boleh mendapatkan sandi hashes.
Inti dari hashing password adalah untuk menambahkan lapisan keamanan ekstra. Jika penyerang dapat memperoleh hash dan garam dari database menggunakan SQL Injection atau cadangan yang tidak aman, maka ia harus menemukan teks biasa dengan paksa. John The Ripper biasanya digunakan untuk memecahkan hash sandi asin.
Tidak menggunakan https merupakan pelanggaran terhadap OWASP Top 10: A9-Insufficient Transport Layer Protection
EDIT:
Jika dalam implementasi Anda, Anda menghitung a sha256(client_salt+plain_text_password)
dan kemudian menghitung hash lain di sisi server sha256(server_salt+client_hash)
maka ini bukan kerentanan yang serius. Namun, itu masih rentan terhadap penyadapan dan pemutaran ulang permintaan. Dengan demikian ini masih jelas merupakan pelanggaran terhadap WASP A9. Namun, ini masih menggunakan intisari pesan sebagai lapisan keamanan.
Hal terdekat yang saya lihat dengan pengganti sisi klien untuk https adalah diffie-hellman dalam pertukaran kunci dalam javascript . Namun, ini mencegah serangan MITM aktif dan dengan demikian sampai teknis merupakan pelanggaran terhadap OWASP A9. Penulis kode setuju bahwa ini bukan pengganti lengkap untuk HTTPS, namun lebih baik daripada tidak sama sekali dan lebih baik daripada sistem hashing sisi klien.
Mengirimkan hash melalui kabel benar-benar mengalahkan tujuan hash, karena penyerang dapat dengan mudah mengirim hash dan melupakan kata sandinya. Singkatnya, sistem yang mengotentikasi menggunakan hash dalam teks yang jelas terbuka lebar dan dapat dikompromikan hanya dengan mengendus jaringan.
Sandi dalam teks biasa tidak pernah (bahkan saat menggunakan HTTPS) keluar dari klien. Ini harus di-hash secara permanen sebelum meninggalkan klien karena server tidak perlu mengetahui kata sandi yang sebenarnya.
Hashing lalu transmisi memecahkan masalah keamanan untuk pengguna malas yang menggunakan kata sandi yang sama di beberapa lokasi (saya tahu saya melakukannya). Namun ini tidak melindungi aplikasi Anda sebagai peretas yang memperoleh akses ke database (atau dengan cara lain dapat memperoleh hashnya) karena peretas hanya dapat mengirimkan hash dan meminta server menerimanya.
Untuk mengatasi masalah ini, Anda tentu saja bisa melakukan hash yang diterima server dan menyebutnya sehari.
Pendekatan saya untuk masalah ini dalam aplikasi web berbasis soket yang saya buat adalah bahwa pada koneksi ke klien, server menghasilkan garam (string acak untuk ditambahkan sebelum hashing) dan menyimpannya di variabel soket, kemudian mengirimkan hash ini kepada klien. Klien mengambil kata sandi pengguna, melakukan hash, menambahkan garam dari server dan meng-hash semuanya, sebelum mengirimkannya ke server. Kemudian dikirim ke server yang membandingkan hash ini dengan hash (hash dalam garam DB +). Sejauh yang saya tahu ini adalah pendekatan yang baik, tetapi sejujurnya saya belum banyak membaca tentang topik ini dan jika saya salah tentang apa pun, saya ingin dikoreksi :)
Gunakan HTTP Digest - ini mengamankan kata sandi bahkan melalui http (tetapi penggunaan terbaik adalah intisari http melalui https)
Wikipedia:
Otentikasi akses intisari HTTP adalah salah satu metode yang disetujui yang dapat digunakan server web untuk menegosiasikan kredensial dengan pengguna web (menggunakan protokol HTTP). Otentikasi intisari dimaksudkan untuk menggantikan penggunaan otentikasi akses Dasar yang tidak terenkripsi, yang memungkinkan identitas pengguna dibuat dengan aman tanpa harus mengirim kata sandi dalam teks biasa melalui jaringan. Otentikasi intisari pada dasarnya adalah aplikasi hashing kriptografi MD5 dengan penggunaan nilai nonce untuk mencegah kriptanalisis.
Tautan: http://en.wikipedia.org/wiki/Digest_access_authentication
Jika Anda ingin melihat penggunaan "kehidupan nyata", Anda dapat melihat phpMyID - penyedia openid php yang menggunakan http digest authentication http://siege.org/phpmyid.php
.. atau Anda dapat memulai dari contoh auth php di http://php.net/manual/en/features.http-auth.php
Ringkasan http rfc: http://www.faqs.org/rfcs/rfc2617
Dari pengujian saya, semua browser modern mendukungnya ...
Jika Anda ingin mengganti kata sandi teks biasa melalui HTTPS dengan kata sandi hash melalui HTTP, maka Anda sedang mencari masalah. HTTPS menghasilkan kunci transaksi bersama secara acak saat membuka saluran komunikasi. Itu sulit untuk dipecahkan, karena Anda cukup terbatas pada memaksa kunci bersama yang digunakan untuk transaksi jangka pendek (relatif). Sedangkan hash Anda bisa saja diendus, diambil off-line dan dicari di meja pelangi atau hanya dipaksakan secara kasar dalam waktu yang lama.
Namun, kebingungan sandi sisi klien dasar (bukan hash) yang dikirim melalui HTTPS memang memiliki beberapa nilai. Kalau tidak salah teknik ini sebenarnya digunakan oleh beberapa bank. Tujuan dari teknik ini bukan untuk melindungi kata sandi agar tidak mengendus melalui kabel. Sebaliknya, ini untuk menghentikan kata sandi agar tidak dapat digunakan untuk alat mata-mata bodoh dan plugin browser yang hanya mengambil setiap permintaan GET / POST HTTPS yang mereka lihat. Saya telah melihat file log yang diambil dari situs web jahat yang 400MB transaksi GET / POST acak diambil dari sesi pengguna. Anda dapat membayangkan bahwa situs web yang hanya menggunakan HTTPS akan muncul dengan kata sandi teks biasa di log, tetapi situs web dengan kebingungan yang sangat mendasar (ROT13) juga akan muncul dengan kata sandi yang tidak segera digunakan.
Jika Anda terhubung ke server https, aliran data antara server dan browser harus dienkripsi. Data tersebut hanya berupa teks biasa sebelum dikirim dan setelah diterima. Artikel Wikipedia
Penafian: Saya sama sekali bukan pakar keamanan - dan saya memposting dengan harapan orang lain akan mengkritik posisi saya karena terlalu berhati-hati atau tidak dapat diperbaiki dan saya akan belajar darinya. Karena itu, saya hanya ingin menekankan bahwa hashing ketika meninggalkan klien Anda tidak berarti Anda tidak perlu melakukan hash di backend sebelum memasukkannya ke dalam database.
Lakukan keduanya
Lakukan keduanya karena:
Hashing dalam perjalanan membantu menutupi kerentanan transportasi, jika koneksi SSL terganggu, mereka masih tidak dapat melihat kata sandi mentah. Tidak masalah dalam hal dapat meniru pengguna resmi, tetapi itu akan melindungi pengguna Anda agar sandi mereka dibaca dalam kaitan dengan email mereka. Kebanyakan orang tidak mengikuti praktik terbaik dan menggunakan kata sandi yang sama untuk banyak akun mereka, jadi ini bisa menjadi kerentanan serius bagi pengunjung Anda.
Jika seseorang, entah bagaimana, dapat membaca kata sandi dari database (ini memang terjadi, pikirkan injeksi SQL), mereka masih tidak akan dapat menjalankan tindakan istimewa yang meniru pengguna melalui API saya. Ini karena asimetri hash; bahkan jika mereka tahu hash yang disimpan di DB Anda, mereka tidak akan tahu kunci asli yang digunakan untuk membuatnya dan itulah yang digunakan middleware auth Anda untuk mengautentikasi. Ini juga mengapa Anda harus selalu menggarami penyimpanan hash Anda.
Memang, mereka dapat melakukan banyak kerusakan lain jika mereka memiliki kebebasan untuk membaca apa yang mereka inginkan dari database Anda.
Saya hanya ingin menekankan di sini bahwa jika Anda memutuskan untuk melakukan hash kunci sebelum keluar dari klien, itu tidak cukup-- hashing backend, im, jauh lebih penting dan inilah alasannya: Jika seseorang mencegat lalu lintas dari Anda klien, lalu mereka akan melihat konten password
bidang. Baik ini hash, atau teks biasa, tidak masalah - mereka dapat menyalinnya secara verbatim untuk meniru klien resmi. (Kecuali Anda mengikuti langkah-langkah yang diuraikan @ user3299591, dan saya sarankan Anda melakukannya). Hashing kolom DB, di sisi lain, adalah sebuah kebutuhan dan sama sekali tidak sulit untuk diterapkan.
Bukankah SSL / TLS menggantikan nonce? Saya tidak melihat nilai tambah dari ini karena SSL / TLS juga melindungi dari Replay Attacks.
Sebenarnya akan kurang aman untuk melakukan hash kata sandi dan mengirimkannya melalui saluran yang tidak dienkripsi. Anda akan mengekspos algoritma hashing Anda pada klien. Peretas bisa saja mengendus hash kata sandi dan kemudian menggunakannya untuk meretas nanti.
Dengan menggunakan HTTPS, Anda mencegah peretas mendapatkan sandi dari satu sumber, karena HTTPS menggunakan dua saluran, keduanya dienkripsi.
Apakah ada keuntungan, dan apakah itu lebih (atau kurang) aman sangat bergantung pada penerapan. Bisa dibilang ada beberapa keuntungan, tetapi jika Anda menerapkannya dengan buruk, Anda pasti dapat membuat solusi yang kurang aman daripada memasukkan bahkan sandi teks biasa.
Ini dapat dilihat dari perspektif dua jenis serangan - satu dengan akses ke lalu lintas jaringan, dan lainnya dengan akses ke database.
Jika penyerang Anda dapat mencegat versi teks biasa dari lalu lintas jaringan, melihat hash kata sandi lebih aman daripada melihat kata sandi dalam teks biasa. Meskipun penyerang masih bisa masuk ke server Anda menggunakan hash itu, itu akan membutuhkan crack brute-force (terkadang sudah dihitung sebelumnya) dari hash itu untuk menentukan kata sandi yang mungkin berguna di sistem lain. Orang-orang harus menggunakan kata sandi yang berbeda pada sistem yang berbeda, tetapi seringkali tidak.
Jika penyerang memperoleh akses ke database, mungkin melalui salinan cadangan, maka Anda ingin memastikan bahwa seseorang tidak dapat masuk hanya dengan pengetahuan itu. Jika, misalnya, Anda menyimpan hash yang diasinkan dengan nama login sebagai hash(login_name+password)
, dan Anda meneruskan hash yang sama dari klien untuk perbandingan langsung, maka penyerang dapat memilih pengguna secara acak, mengirim hash yang telah dibaca dari database dan masuk sebagai pengguna tersebut tanpa mengetahui sandinya, meningkatkan cakupan pelanggaran. Dalam hal ini, mengirim kata sandi dalam teks biasa akan lebih aman karena penyerang perlu mengetahui teks biasa untuk masuk, bahkan memiliki salinan database. Di sinilah penerapan adalah kuncinya. Baik Anda mengirim sandi teks biasa atau hash sisi klien dari sandi tersebut, Anda harus mencirikan nilai tersebut di sisi server dan membandingkan hash tersebut dengan hash yang disimpan dalam catatan pengguna.
Konsep yang perlu diperhatikan: