it-swarm-id.com

Apa yang harus ditransfer? Kata sandi atau hash-nya?

Katakanlah di basis data saya, saya menyimpan kata sandi yang dipecah dengan garam dengan hash yang cukup mahal (scrypt, 1000 putaran SHA2, apa pun).

Setelah masuk, apa yang harus saya transfer melalui jaringan dan mengapa? Kata sandi atau hash-nya?

Apakah mungkin untuk melindungi login seperti itu melalui saluran yang tidak dienkripsi seperti HTTP?

40
Konrad Garus

Jika Anda mentransfer hash dari klien, ini tidak memberikan manfaat keamanan, dan menjadikan hash tidak berguna:
Jika pengguna dapat masuk dengan mengirimkan hash ke server, maka hash adalah kata sandi yang efektif.

61
AviD

Jika protokol otentikasi Anda adalah tentang mengirim kata sandi kepada server, atau hash kata sandi, dengan HTTP biasa, maka ini pada dasarnya sangat lemah, karena dua alasan:

  • Seseorang yang memata-matai telepon dapat merekam apa yang dikirim klien. Jika hanya mengirim byte ini memberikan akses, maka penyerang bisa mengirimnya lagi. Itu serangan replay . Masalah ini adalah apa yang disinggung @AviD dalam jawabannya. Tidak ada jumlah hashing yang akan memperbaikinya. Beberapa protokol mencoba untuk memperbaiki masalah ini dengan memasukkan "tantangan" dari server (nilai acak, dibuat lagi untuk setiap koneksi), untuk di-hash bersama dengan kata sandi pada klien; itulah yang otentikasi HTTP Digest tentang.

  • Bahkan jika otentikasi berhasil, ini masih HTTP biasa, jadi data apa pun yang akan dikirim sesudahnya akan rentan terhadap penyadapan dan perubahan oleh penyerang. Jika media transportasi tidak terlindungi, maka otentikasi akan mencegah hanya penyerang yang paling tidak canggih. Di sinilah HTTP Digest gagal.

Oleh karena itu, Anda benar-benar membutuhkan SSL (alias HTTPS), tidak hanya untuk menyampaikan kata sandi atau hashnya, tetapi juga sisa percakapan antara klien dan server .


Saya selanjutnya berasumsi bahwa protokol dijalankan dalam terowongan SSL. Anda benar ingin menggunakan hash lambat seperti bcrypt atau PBKDF2; perhatikan bahwa garam juga diperlukan untuk mencegah pembagian biaya (mis. tabel prakomputasi). Slow hashing hashing digunakan untuk mengatasi kelemahan intrinsik kata sandi. Sekarang, Anda mungkin ingin memuat beberapa upaya hashing pada klien. Ini boleh berhasil, tetapi menimbulkan beberapa masalah praktis:

  • Karena pemrosesan kata sandi harus menyertakan garam, yang baru untuk setiap instance kata sandi, maka garam tersebut harus disampaikan kepada klien, sehingga klien dapat memasukkannya dalam hashing yang ia lakukan. Ini meningkatkan kompleksitas protokol: klien harus terlebih dahulu mengirim nama pengguna ke server, kemudian server harus mengirim kembali garam, dan (hanya kemudian) dapat klien mulai hash password. Ini adalah satu lagi perjalanan pulang-pergi jaringan daripada dengan "kirim nama pengguna dan kata sandi sebagai satu POST permintaan").

  • Hashing lambat adalah tentang menerima menghabiskan banyak CPU pada setiap kata sandi, sehingga penyerang juga harus menghabiskan banyak CPU pada setiap kata sandi. Tetapi jika CPU yang dihabiskan ada pada klien, maka kami tidak dapat menaikkannya sebanyak yang kami inginkan, karena: 1) ada klien yang memiliki CPU sangat sedikit (katakan beberapa smartphone atau tablet murah), dan 2) konteks Web menyiratkan menggunakan Javascript, dan kinerja Javascript benar-benar buruk ketika datang ke hashing (katakan setidaknya 20 kali lebih lambat dari kode C).

Oleh karena itu kebijaksanaan umum adalah membuat bagian dari kata sandi hashing pada klien tidak sepadan dengan usaha.

24
Thomas Pornin

Kedua opsi tidak aman.

Mentransfer kata sandi akan membuat protokol Anda menjadi teks biasa. Mentransfer hash, akan membuat Anda rentan terhadap serangan replay.

APOP adalah implementasi login untuk protokol POP. Ini memungkinkan protokol menjaga kerahasiaan kata sandi dari pendengar di jaringan. Kelemahan dari hal ini adalah bahwa klien dan server perlu mengetahui kata sandi dalam teks biasa, karena ini adalah rahasia bersama. Sebelum protokol, klien dan server memiliki <password> Komunikasi protokol pada dasarnya seperti ini:

  1. Klien terhubung ke server dan mengirim token acak (T1)
  2. Server mengirimkan token acak (T2)
  3. Klien mengirim M = sha (T1 + T2 + <kata sandi: salinan klien>) ke server
  4. Server memeriksa apakah sha (T1 + T2 + <kata sandi: salinan server>) cocok dengan M (hash baru saja diterima).

Di sini, server mengetahui keajaiban dan kata sandi, dan dapat menentukan apakah pengguna mengetahui kata sandi yang benar tanpa memaparkannya kepada pendengar mana pun.

Praktik terbaik adalah menyimpan hash dengan aman di database, dan mengandalkan saluran terenkripsi.

4