it-swarm-id.com

Apakah kata sandi HMAC-ed lebih aman daripada kata sandi bcrypt-ed atau scrypt-ed?

Diberi pilihan, HMAC mana yang harus saya pilih, untuk menyimpan kata sandi dengan aman atau perpustakaan bcrypt atau scrypt?

25
user917279

Untuk memberikan Anda ide yang tepat tentang masalah dan seluk beluk komputasi hash kata sandi, serta mengapa HMAC tidak cocok untuk masalah ini, saya akan memberikan jawaban yang lebih luas daripada yang sebenarnya diperlukan untuk langsung menjawab pertanyaan.

Algoritma hash HMAC, pada dasarnya, hanyalah versi kunci dari algoritma hash normal. Biasanya digunakan untuk memverifikasi integritas dan keaslian. Notasi yang biasa dari ini adalah H(m,k) = h, di mana H adalah algoritma hash HMAC, m adalah pesan, k adalah kuncinya, dan h adalah hash yang dihasilkan. Idenya adalah bahwa dua pihak yang berbagi rahasia k dapat memverifikasi bahwa orang lain adalah penulis m. Lebih jauh, seorang penyerang tidak dapat memalsukan hash pesan tanpa mengetahui k.

Ini dilakukan sebagai berikut:

  1. Alice dan Bob sama-sama tahu kunci rahasia bersama k.
  2. Alice menulis pesan m, dan menghitung hash HMAC menggunakan k, mis. H(m,k) = h.
  3. Alice mengirim pesan m dan hash h kepada Bob.
  4. Bob menghitung H(m,k) dan membandingkannya dengan hash h yang dikirim Alice. Jika hash cocok, dia tahu bahwa Alice mengirim pesan, dan bahwa itu tidak diubah setelah hash.

Sekarang setelah Anda memahami apa itu HMAC, mari beralih ke apa yang Anda sungguh ingin Anda lakukan - menyimpan kata sandi dalam database.

Bertahun-tahun yang lalu, itu adalah praktik standar untuk menyimpan kata sandi dalam plaintext di basis data. Ini adalah ide yang buruk karena, ketika database dikompromikan, penyerang mendapatkan semua kata sandi. Untuk mengatasi ini, kami mulai hashing password dalam database menggunakan algoritma hash kriptografi satu arah. MD5 menjadi populer, tetapi kelemahan (tabrakan, preimage parsial, dll) ditemukan di dalamnya berarti tidak lagi direkomendasikan. Banyak orang pindah ke SHA1, yang lebih aman.

Masalah dengan pendekatan ini adalah bahwa itu mungkin untuk membangun sebuah tabel besar hash dan plaintext yang sesuai. Ini disebut Rainbow table . Mereka bekerja pada konsep bahwa lebih efisien untuk menghitung daftar besar hash untuk semua kata sandi yang mungkin (dalam satu set tertentu) dan kemudian menyimpannya, sehingga dapat dengan cepat dimintai pertanyaan di kemudian hari. Jadi, alih-alih mem-hash individual hash, menjadi mungkin untuk hanya meminta database hash dan plaintextnya segera dikembalikan.

Untuk memperbaiki ini, kutu buku keamanan menemukan garam. Garam adalah nilai acak unik yang besar yang ditambahkan ke kata sandi sebelum di hash. Garam ini disimpan dengan hash, sehingga bisa dihitung lagi nanti. Jadi, kita menghitung H(m+s) = h, lalu menyimpan h dan s dalam database. Ini memberikan signifikan perlindungan terhadap tabel Rainbow karena pada dasarnya memerlukan tabel Rainbow terpisah yang akan dihasilkan untuk setiap garam.

Jadi, orang-orang jahat beralih kembali ke serangan kamus dan brute-force cracking. Dengan kemajuan komputasi GPU, menjadi mungkin untuk menghitung miliaran hash per detik pada kartu grafis yang cukup kuat. Bahkan, orang telah membangun komputer yang dapat menghitung hampir 50 miliar MD5 hash per detik - cukup mengesankan/menakutkan. Alasan GPU mampu melakukan ini adalah karena mereka dirancang untuk melakukan sejumlah besar operasi skalar paralel. Operasi skalar adalah operasi matematika dan logika yang tidak melibatkan cabang - yaitu mereka tidak perlu melakukan banyak/"jika x maka lakukan y". Algoritma hash kriptografi cenderung masuk ke dalam model ini.

Untuk membuat ini sulit, kita harus membuat operasi hash cukup lambat untuk membuat brute memaksa tidak mungkin. Algoritma hash normal (mis. SHA1) dirancang untuk menjadi cepat, yang membuatnya tidak cocok untuk tujuan ini. HMAC menambahkan sangat sedikit overhead dan tidak ada margin keamanan tambahan, jadi itu juga tidak banyak digunakan di sini.

Membuat algoritma hash kriptografi lambat lebih mudah dikatakan daripada dilakukan - sangat sulit untuk menghasilkan yang lambat, tidak dapat direduksi (mis. Tidak dapat dioptimalkan di luar keadaan saat ini) dan aman. Ada tiga fungsi hash populer yang dapat melakukan ini: PBKDF2 , bcrypt , dan scrypt . Ini dikenal sebagai fungsi derivasi kunci adaptif, karena mereka menerima nilai faktor kerja bersama dengan plaintext dan garam. Faktor kerja mengubah jumlah waktu yang diperlukan untuk menghitung hash, dan dirancang untuk melindungi terhadap peningkatan perangkat keras di masa depan.

Jadi, untuk algoritme derivasi kunci adaptif H, kami menghitung H(m,s,w) = h, di mana m adalah pesan (kata sandi), s adalah garam, dan w adalah faktor kerja. h yang dihasilkan biasanya berisi s dan w, sehingga fungsi verifikasi nantinya dapat menghitung hash yang sama menggunakan parameter yang sama. Faktor kerja umumnya mengontrol jumlah iterasi yang dilakukan oleh primitif kriptografi internal. Tujuannya adalah untuk membuat perhitungan yang cukup lama untuk membuat cracking tidak layak, tetapi tidak melebihi sumber daya yang kita miliki.

Untuk memberikan keamanan yang lebih baik terhadap perengkahan berbasis perangkat keras khusus, scrypt memastikan bahwa komputasi hash baik untuk hard-CPU dan hard-memory, yaitu membutuhkan CPU dan sumber daya memori yang signifikan untuk menghasilkan nilai hash. Ini penting, karena FPGAs biasanya memiliki akses ke memori langsung yang sangat sedikit.

Sekarang, pertanyaan yang jelas muncul: jika saya mengatur situs saya untuk menggunakan bcrypt, bukankah itu berarti server saya harus menghitung hash intensif CPU sepanjang waktu? Nah, jika Anda menjalankannya di server Anda, maka ya, itu sesuatu yang perlu dipertimbangkan. Solusi yang lebih baik adalah meminta klien menghitung hash, kemudian mengirimkannya ke server melalui SSL. Server kemudian dapat membandingkannya dengan nilai dalam database. Ini memastikan bahwa hash kata sandi tidak dapat dengan mudah dipecahkan jika dicuri (mis. Melalui kompromi basis data), dan bahwa server Anda tidak kewalahan oleh overhead perhitungan hash kata sandi. Untuk situs web, Anda dapat menggunakan jsBcrypt .  Pembaruan: Metode ini telah ditunjukkan sebagai cacat oleh komentator di bawah ini. Jangan gunakan itu.

Semoga ini memberi Anda gambaran yang baik tentang situasi, dan mengapa HMAC tidak cocok untuk penggunaan seperti ini.

37
Polynomial

HMAC adalah kode otentikasi pesan ; menggunakan kunci. Bcrypt tidak. Dengan demikian, pilihannya tidak netral; Anda tidak dapat menganggap semua hal itu setara, karena mereka tidak sama.

Meskipun secara nominal memeriksa integritas, kebetulan bahwa HMAC (bila digunakan dengan fungsi hash yang cukup aman, mis. SHA-256 atau bahkan SHA-1) berperilaku seperti "fungsi hash dengan kunci". Ini bukan properti generik dari algoritma MAC, tetapi bekerja dengan HMAC (itu sebabnya ia dapat digunakan sebagai dasar untuk generator acak yang disebut Hmac_DRBG ). Ini membuat HMAC pilihan potensial untuk hashing kata sandi.

Jika Anda "hash" kata sandi Anda dengan HMAC, dan penyerang bisa mengambil file/database kata sandi hash Anda tetapi bukan kunci HMAC , maka penyerang akan tidak dapat memecahkan kata sandi. Dalam skenario itu, HMAC "lebih baik" dari pada bcrypt/scrypt. Namun, ini adalah kasus Edge. Kami hash kata sandi karena kami khawatir tentang skenario pinggiran di mana penyerang bisa melanggar keamanan cukup untuk mendapatkan read-only akses ke bagian dari file server, tetapi tidak a baca-tulis akses. Metode hash-with-HMAC adalah untuk skenario fringe-squared di mana penyerang read-only bisa mendapatkan kata sandi hash tetapi bukan kunci, yang tetap disimpan di server yang sama.

Jika penyerang bisa mendapatkan kunci, maka HMAC menjadi fungsi hash sederhana baginya, dan dalam hal itu HMAC jauh lebih buruk daripada bcrypt, karena itu unsalted dan terlalu sial cepat. Ini seperti jika kata sandi tempat hash dengan sepasang doa SHA-1. Skenario itu tidak kalah memungkinkan dari yang sebelumnya, dan karenanya kita harus mempertimbangkan penggunaan HMAC saja sebagai terlalu berisiko .


Untuk yang terbaik dari kedua dunia , terapkan HMAC pada kata sandi pengguna, lalu memproses output HMAC melalui - bcrypt ; Anda akan menyimpan output bcrypt. Karena implementasi bcrypt mengharapkan kata sandi sebagai string karakter, Anda harus menyandikan output HMAC (heksadesimal, Base64 ...).

Ini lebih kompleks daripada bcrypt saja, karena menggunakan dua fungsi, bukan satu, dan karena kuncinya (yang membawa seluruh masalah manajemen kunci: pembuatan, penyimpanan, pencadangan ...). Karena kompleksitasnya buruk, saya akan merekomendasikan untuk tidak melakukannya; cukup gunakan bcrypt saja, dan jangan tambahkan HMAC. Namun, ini adalah panggilan Anda; jika Anda benar-benar inginkan HMAC, gunakan selain bcrypt, bukan bukan bcrypt.

(Catatan: itu bcrypt pada output HMAC, bukan sebaliknya, yang tidak akan bekerja karena garam yang termasuk dalam output bcrypt.)

9
Thomas Pornin

HMAC dirancang untuk menjadi sangat cepat dan dalam konteks ini cara yang baik untuk menambahkan garam ke kata sandi, bukan hanya menambahkannya. Bcrypt jauh lebih lambat karena inisialisasi lambat, sementara scrypt bahkan lebih lambat daripada Bcrypt karena sengaja dirancang sedemikian rupa. Scrypt dirancang untuk membuatnya dengan biaya yang sangat mahal. Ini menghabiskan banyak CPU, memori dan juga lambat digunakan pada GPU.

Lebih lanjut tentang scrypt

2
Matrix