it-swarm-id.com

Dengan PBKDF2, apa ukuran Hash yang optimal dalam byte? Bagaimana dengan ukuran garamnya?

Saat membuat hash dengan PBKDF2, ini memungkinkan pengembang untuk memilih ukuran hash. Apakah lebih lama selalu lebih baik? Juga, bagaimana dengan ukuran garam acak? Haruskah ukurannya sama dengan hash?

EDIT: Terutama dalam hashing passwords.

27
blesh

Untuk fungsi hash, Anda ingin menggunakan fungsi yang jenis platformnya paling efisien (yang akan menghasilkan lebih banyak perhitungan hash per detik dan per dolar) adalah mesin yang ingin Anda gunakan (mis. PC). Itu karena Anda berada dalam perlombaan senjata dengan penyerang, dan penyerang dapat membeli jenis perangkat keras lain untuk mendapatkan keunggulan atas diri Anda (seperti GPU). GPU sangat bagus dalam aritmatika 32-bit, tetapi tidak pada aritmatika 64-bit, sedangkan PC (dalam mode 64-bit) akan cukup cepat pada yang terakhir.

Dengan demikian, gunakan fungsi hash yang berjalan pada operasi aritmatika 64-bit. Ini menunjuk pada SHA-512 .

PBKDF2 adalah fungsi derivasi kunci : ini menghasilkan output dengan ukuran yang dapat dikonfigurasi. Untuk hashing kata sandi, Anda ingin ukurannya cukup besar untuk mencegah serangan preimage generik (mis. Mencoba kata sandi acak hingga kecocokan ditemukan), jadi ini perlu, katakanlah, setidaknya 80 bit output. Jika hanya untuk membuat keamanan lebih meyakinkan untuk yang tidak waspada, dan juga untuk estetika, gunakan kekuatan 2: a output 128-bit . Tidak berguna untuk melampaui itu.

Garam harus unik - seunik mungkin. Cara mudah untuk mencapai nilai garam unik adalah dengan menghasilkan garam dengan PRNG yang kuat secara kriptografis : kemungkinan menggunakan kembali nilai garam akan cukup rendah untuk diabaikan jika garam acak ini cukup besar, dan "cukup besar "Berarti" 128 bit ". Jadi gunakan garam 128-bit acak .

Secara pribadi, saya lebih suka bcrypt lebih dari PBKDF2 untuk hashing kata sandi.

24
Thomas Pornin

Menurut standar PBKDF2, ukuran minimum yang disarankan untuk garam adalah 64 bit, meskipun saya pribadi merekomendasikan 128 bit atau lebih tinggi untuk margin keamanan yang layak. Ukuran garam tidak tergantung pada hash pilihan Anda.

Sejauh menyangkut keamanan, saya sarankan memilih panjang kunci turunan setidaknya ukuran yang sama dari output garam Anda, dengan minimum 256 bit. Setiap ukuran hash kurang dari 256-bit di bawah batas keamanan dari sebagian besar fungsi hash modern.

Memilih panjang kunci turunan yang kurang dari panjang keluaran fungsi hash tidak masuk akal, kecuali Anda menggunakan kunci untuk blok sandi yang tidak bisa menangani kunci dengan ukuran itu.

Dalam hal keamanan optimal, saya sarankan SHA-512 sebagai PRF, dengan kunci turunan 512-bit, garam 128-bit, dan sebanyak iterasi yang sesuai dengan situasi Anda.

11
Polynomial

Jika platform pilihan Anda adalah .NET, ada artikel OWASP yang didedikasikan khusus untuk kelas Rfc2898DeriveBytes . Catatan khusus (penekanan milik saya):

Implementasi .NET bawaan Rfc2898DeriveBytes membatasi pengguna untuk satu fungsi psudorandom - HMAC dengan SHA-1 . Ini dapat diterima di sebagian besar skenario hari ini, tetapi di masa depan, fungsi hashing yang lebih kompleks mungkin diperlukan.

Menggunakan PBKDF2 untuk penyimpanan kata sandi, seseorang seharusnya tidak pernah menghasilkan lebih banyak bit daripada ukuran fungsi hash dasar. Dengan PBKDF2-SHA1 ini adalah 160 bit atau 20 byte . Menghasilkan lebih banyak bit tidak membuat hash lebih aman, tetapi menghabiskan lebih banyak waktu bagi bek tanpa biaya bagi penyerang. Seorang penyerang hanya akan membandingkan fungsi hash keluaran berukuran pertama yang menghemat waktu untuk menghasilkan pengaturan ulang keluaran PBKDF2.

Mereka juga memiliki contoh kode, yang saya sesuaikan menurut panduan jawaban lainnya:

public static string Hash(string str)
{
    // Generate the hash, with an automatic 16 byte salt
    using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(str, 16))
    {
        rfc2898DeriveBytes .IterationCount = 10000 // or whatever you can afford
        byte[] hash = rfc2898DeriveBytes.GetBytes(20);
        byte[] salt = rfc2898DeriveBytes.Salt;
        return Convert.ToBase64String(salt) + "|" + Convert.ToBase64String(hash);
    }
}
4
Ohad Schneider