Dari mana seharusnya nilai hash garam berasal?


12

Saat menambahkan nilai garam ke nilai hash untuk sesuatu seperti kata sandi yang tidak dapat disimpan dalam teks biasa, dari mana tempat terbaik untuk mendapatkan nilai garam? Untuk konteks, mari kita anggap ini untuk kata sandi pada login halaman web.


@ DevArt, saya pikir itu lebih cocok di sini karena memerlukan jawaban yang sangat subjektif. Nilai garam dapat ditarik dari mana saja, jadi saya bertanya "Di mana menurut Anda adalah lokasi yang paling aman untuk menarik nilai garam dari: klien atau server?"
Morgan Herlocker

Jawaban:


7

Saya biasanya memiliki kolom created TIMESTAMPdi tabel pengguna sehingga saya bisa melihat ketika pengguna mendaftar. Saya tidak suka menambahkan kolom tambahan untuk Garam, jadi saya menggunakan kolom cap waktu sebagai garam:

SHA1(password + created)

Saya kemudian berasumsi bahwa ketika pengguna masuk lagi, Anda menarik tanggal berdasarkan nama pengguna ketika Anda mengulangi untuk verifikasi?
Morgan Herlocker

1
@ Profil: Ya, sama seperti yang Anda lakukan jika Anda memiliki kolom khusus untuk garam, jadi tidak ada perbedaan dalam perspektif itu.
Jonas

7

Apakah itu penting?

Garam memiliki dua tujuan. Itu membuatnya tidak praktis untuk menggunakan tabel besar dari kata sandi yang sudah di prehashed ("rainbow tables") dan itu membuat kata sandi yang identik terlihat berbeda dalam daftar hash. Membuat kata sandi yang identik terlihat berbeda membantu menghindari masalah ketika beberapa orang menggunakan satu kata sandi tertentu, yang mungkin merupakan kata sandi yang umum lemah.

Oleh karena itu, setiap akun harus memiliki garam uniknya sendiri, dan garamnya tidak boleh terlalu diprediksi, dalam arti tidak akan ada kelompok garam yang mungkin terjadi. (Jika banyak situs dimulai pada 1 dan dihitung, orang jahat dapat membuat tabel pelangi termasuk garam jumlah rendah, misalnya.) Mereka tidak harus acak dalam arti apa pun selain yang umumnya tidak dapat diprediksi. Mereka bukan rahasia lagi dari hash itu sendiri, sehingga mereka tidak perlu secara khusus tidak dapat diterima.

Gunakan metode yang mudah untuk menghasilkan garam. Jika ada banyak nilai garam potensial (sistem Unix awal sering menggunakan dua byte, untuk jumlah 65536) dibandingkan dengan jumlah akun, penugasan semi-acak hampir tidak akan pernah memberikan garam duplikat.


1
Saya secara umum telah melihat masalah kedua - kata sandi yang identik terlihat berbeda - ditangani dengan merangkai nama pengguna, garam, dan kata sandi dan hashing seluruh string. Itu menghilangkan kebutuhan untuk menghasilkan garam unik per akun.
Justin Cave

1
@ Justin: menarik, saya belum pernah melihat nama pengguna yang digunakan sebagai bagian dari hash, tapi itu memang cara yang baik untuk menambahkan beberapa entropi. Saya masih menggunakan garam pseudo-acak, hanya karena tidak memerlukan banyak biaya untuk menghasilkan satu.
Matthieu M.

2
@Matthieu Dengan sisi negatifnya harus menyimpannya di suatu tempat, dan jika kedua sisi transaksi membutuhkannya, harus juga mengirimkannya. Dengan nama pengguna, kedua belah pihak sudah mengetahuinya.
Matius Frederick

2
@Justin: Dalam hal ini Anda menggunakan nama pengguna sebagai garam. Ini menjawab kedua tujuan dari garam: membuat tabel pelangi menjadi tidak praktis, dan membuat kata sandi yang sama terlihat berbeda.
David Thornley

@ David - Benar, Anda dapat melihatnya sebagai nama pengguna yang menjadi bagian dari garam. Saya masih menginginkan garam tambahan sehingga penyerang tidak dapat menggunakan tabel pelangi untuk menemukan kombinasi nama pengguna / kata sandi. Tanpa garam eksplisit, Anda hanya menambah ukuran string yang dibutuhkan penyerang dari tabel pelangi dengan panjang nama pengguna (yang cenderung pendek dan huruf besar atau kecil). Garam konstan cukup untuk menggagalkan serangan tabel pelangi kecuali situs Anda cukup besar sehingga penyerang akan menghasilkan tabel pelangi spesifik lokasi.
Justin Cave

3

Setiap kali Anda ingin menyimpan kata sandi baru (pendaftaran, pengaturan ulang kata sandi, pembaruan kata sandi), satu teknik yang baik adalah:

  • menghasilkan garam baru
    • menggunakan generator nomor acak semu cryptographically aman
    • menggunakan ukuran garam yang layak - nilai yang baik adalah ukuran blok algoritma hash yang mendasarinya (mungkin SHA-256)
  • menghasilkan token kata sandi baru
    • membuat fungsi hmac dari algoritma hash yang mendasarinya (mungkin SHA-256) menggunakan garam sebagai kunci hmac
    • for i in (0...65536) { password = hmac(password) }
    • hasil aplikasi berulang dari fungsi hmac adalah token kata sandi
  • menyimpan garam dan token kata sandi
    • jangan menyimpan kata sandi asli
    • opsional menyimpan algoritma hash yang mendasarinya dan peregangan untuk dapat ditemukan

1

Leverage kerangka kerja. Di. NET Anda bisa menggunakan RNGCryptoServoiceProvider ...

        // If salt is not specified, generate it on the fly.
        if (saltBytes == null)
        {
            // Define min and max salt sizes.
            int minSaltSize = 4;
            int maxSaltSize = 8;

            // Generate a random number for the size of the salt.
            Random  random = new Random();
            int saltSize = random.Next(minSaltSize, maxSaltSize);

            // Allocate a byte array, which will hold the salt.
            saltBytes = new byte[saltSize];

            // Initialize a random number generator.
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

            // Fill the salt with cryptographically strong byte values.
            rng.GetNonZeroBytes(saltBytes); 
        }

Kerangka kerja lain harus memiliki kelas serupa yang dapat Anda manfaatkan. Untuk mencapai keacakan perangkat lunak sering kali mempekerjakan pengguna versus Randomsebagaimana disebutkan di atas. Menggerakkan mouse secara acak di area yang ditentukan untuk memberikan garam adalah opsi yang digunakan oleh TrueCrypt. Itu bermuara pada kebutuhan spesifik Anda dan tingkat keamanan; karena garam Anda bisa saja !@#$%.


1

Anda menghasilkan sisi server garam dan menugaskannya ke akun pengguna pada saat pembuatannya. Lebih baik gunakan beberapa API crypto-generation yang tersedia dengan kerangka kerja Anda tetapi pada prinsipnya urutan apa pun akan dilakukan.

Biasanya barang disimpan seperti ini:

User
-------------------
ID
Username
PasswordHashWithSalt

Contoh:

PasswordHashWithSalt =

A15CD9652D4F4A3FB61A2A422AEAFDF0DEA4E703 j5d58k4b56s8744q


Tetapkan berdasarkan apa? Apakah itu tidak harus berasal dari beberapa nilai yang akan tetap di tempat sehingga dapat direplikasi ketika pengguna masuk kembali setelah pembuatan?
Morgan Herlocker

Dengan "menetapkan" maksud saya menghasilkan garam per pasangan nama pengguna / kata sandi (akun) dan menyimpannya dalam database. Ketika Anda perlu melakukan login, Anda menggunakan garam yang disimpan itu untuk memeriksa beberapa hal.

1

Gunakan bcrypt dan baca artikel ini karena hash yang normal saja bukan perlindungan serius di zaman sekarang ini.

Pertimbangkan untuk menggunakan protokol kata sandi nol pengetahuan SDR yang memiliki banyak pustaka sumber terbuka dan bebas paten.

SDR membutuhkan garam dan tempat terbaik untuk mendapatkannya adalah klien; mengatur waktu penekanan tombol mereka, gerakan mouse, hash variabel lingkungan mereka, angka acak, waktu pembuatan file di folder temp mereka, untuk membuat garam pada akhirnya dengan cara yang tak terduga jauh dari server Anda. SDR mengambil garam, kata sandi besar, kata sandi pengguna dan menghasilkan kunci verifikasi. Anda tidak menyimpan kata sandi yang tidak pernah keluar dari mesin mereka tetapi Anda dapat memverifikasi bahwa mereka memiliki kata sandi yang sesuai dengan kunci verifikasi dan garam. Itu kebal dari manusia di tengah dan serangan kamus. Enkripsi kunci dan garam di kolom basis data hanya untuk memastikan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.