Apakah BCrypt algoritma hashing yang baik untuk digunakan dalam C #? Di mana saya bisa menemukannya? [Tutup]

129

Saya telah membaca bahwa ketika membuat kata sandi, banyak programmer merekomendasikan menggunakan algoritma BCrypt.

Saya pemrograman dalam C # dan bertanya-tanya apakah ada yang tahu implementasi yang baik untuk BCrypt? Saya menemukan halaman ini , tetapi saya tidak benar-benar tahu apakah itu palsu atau tidak.

Apa yang harus saya ketahui ketika memilih skema hashing kata sandi? Apakah BCrypt implementasi yang 'baik'?

Svish
sumber

Jawaban:

148

Pertama, beberapa istilah yang penting:

Hashing - Tindakan mengambil string dan menghasilkan urutan karakter yang tidak dapat dikembalikan ke string asli.

Symmetric Encryption - (Biasanya hanya disebut sebagai 'enkripsi') - Tindakan mengambil string dan menghasilkan urutan karakter yang dapat didekripsi ke string asli melalui penggunaan kunci enkripsi yang sama yang dienkripsi itu.

Rainbow Table - tabel pencarian yang berisi semua variasi karakter yang hash dalam algoritma hashing tertentu.

Garam - string acak yang dikenal ditambahkan ke string asli sebelum hash.

Untuk .NET Framework, Bcrypt belum memiliki implementasi referensi terverifikasi . Ini penting karena tidak ada cara untuk mengetahui apakah ada kelemahan serius dalam implementasi yang ada. Anda bisa mendapatkan implementasi BCrypt untuk .NET di sini . Saya tidak cukup tahu tentang kriptografi untuk mengatakan apakah itu implementasi yang baik atau buruk. Kriptografi adalah bidang yang sangat dalam. Jangan mencoba membangun algoritma enkripsi Anda sendiri . Serius.

Jika Anda ingin menerapkan keamanan kata sandi Anda sendiri, maka Anda perlu melakukan beberapa hal:

  1. Gunakan algoritma hash yang relatif aman .
  2. Garam setiap kata sandi sebelum di-hash.
  3. Gunakan garam yang unik dan panjang untuk setiap kata sandi , dan simpan garam dengan kata sandi.
  4. Membutuhkan kata sandi yang kuat .

Sayangnya, bahkan jika Anda melakukan semua ini, seorang hacker yang gigih masih berpotensi menemukan kata sandinya, itu hanya akan memakan waktu yang sangat lama. Itu musuh utama Anda: Waktu .

The algoritma bcrypt bekerja karena butuh lima lipat lebih lama untuk hash password dari MD5 ; (dan masih lebih lama dari AES atau SHA-512). Ini memaksa peretas untuk menghabiskan lebih banyak waktu untuk membuat tabel pelangi untuk mencari kata sandi Anda, membuatnya jauh lebih kecil kemungkinannya bahwa kata sandi Anda akan terancam diretas.

Jika Anda salting dan hashing kata sandi Anda, dan setiap garam berbeda, maka peretas potensial harus membuat tabel pelangi untuk setiap variasi garam , hanya untuk memiliki tabel pelangi untuk satu kata sandi + hash asin. Itu berarti jika Anda memiliki 1 juta pengguna, seorang hacker harus menghasilkan 1 juta tabel pelangi. Jika Anda menggunakan garam yang sama untuk setiap pengguna, maka peretas hanya perlu membuat 1 tabel pelangi untuk berhasil meretas sistem Anda.

Jika Anda tidak memberi salin kata sandi, maka yang harus dilakukan penyerang adalah menarik tabel Rainbow yang ada untuk setiap implementasi di luar sana (AES, SHA-512, MD5) dan hanya melihat apakah ada yang cocok dengan hash. Ini sudah dilakukan , penyerang tidak perlu menghitung tabel Rainbow ini sendiri .

Bahkan dengan semua ini, Anda harus menggunakan praktik keamanan yang baik . Jika mereka dapat berhasil menggunakan vektor serangan lain (XSS, SQL Injection, CSRF, et. Al. ) Di situs Anda, keamanan kata sandi yang baik tidak masalah. Itu terdengar seperti pernyataan yang kontroversial, tetapi pikirkan: Jika saya bisa mendapatkan semua informasi pengguna Anda melalui serangan injeksi SQL, atau saya bisa meminta pengguna Anda untuk memberikan saya cookie mereka melalui XSS, maka tidak masalah seberapa baik kata sandi Anda keamanan .

Sumber lain:

  1. Jeff Atwood: .NET Enkripsi Sederhana (bagus untuk ikhtisar hashing)
  2. Jeff Atwood: Saya baru saja masuk sebagai Anda
  3. Jeff Atwood: Anda mungkin salah menyimpan kata sandi
  4. Jeff Atwood: Speed ​​Hashing

Catatan: Harap rekomendasikan sumber daya lain yang baik. Saya pasti telah membaca selusin artikel oleh puluhan penulis, tetapi hanya sedikit yang menulis sejelas itu tentang subjek seperti yang dilakukan Jeff. Harap edit dalam artikel saat Anda menemukannya.

George Stocker
sumber
mungkin tambahkan ke paragraf garam Anda bahwa garam harus dipilih secara acak
Jacco
2
@Jacco Panggilan bagus, ditambahkan. Meskipun itu tidak terlalu penting. Anda cukup menggunakan stempel waktu masuk untuk mendapatkan garam. Perbedaannya adalah penyerang kemudian perlu menghitung ulang tabel pelangi untuk setiap garam. Itulah yang membuatnya sulit, bukan karena itu dipilih secara acak. Menjadikannya acak akan menambah lapisan pendidikan usang, tapi itu tidak berguna begitu penyerang dapat melihat basis data Anda (yang merupakan masalah yang menyebabkan semua sakit hati kami di tempat pertama).
George Stocker
3
Tidak juga, garam tidak harus dirahasiakan, hanya unik untuk setiap contoh. Karena unik (seperti halnya di seluruh dunia) tidak mungkin, acak adalah hal terbaik berikutnya. Juga, cap waktu bukanlah garam yang baik karena tidak ada cukup entropi.
Jacco
7
Saya akan mempermasalahkan pernyataan Anda "Jika mereka berhasil menggunakan XSS atau injeksi SQL, keamanan kata sandi yang baik tidak masalah." Sebaliknya, jika mereka berhasil XSS atau SQL menyuntikkan situs Anda, keamanan kata sandi yang baik bahkan lebih penting. Kuncinya di sini adalah "pertahanan mendalam" - Anda harus memperketat keamanan sejauh praktis di setiap lapisan aplikasi Anda.
jammycakes
2
@jammycakes Absolutely; maksud saya hilang: Anda tidak bisa hanya mengatakan, 'Hei, kita hash dan beri garam kata sandi kami, "kami baik-baik saja!"
George Stocker
74

Anda tidak boleh menggunakan BCrypt di .NET. Anda harus menggunakan PBKDF2 sebagaimana halnya dengan implementasi .NET framework bawaan. Ini adalah satu-satunya implementasi yang diverifikasi secara cryptographically tersedia di. NET bersama dengan menjadi algoritma yang direkomendasikan oleh NIST .

StackId sebelumnya menggunakan BCrypt dan pindah ke PBKDF2 karena alasan ini:

Bagi mereka yang penasaran, kami membuat kata sandi dengan PBKDF2. Kode yang relevan ada di sini ( http://code.google.com/p/stackid/source/browse/OpenIdProvider/Current.cs#1135 ), melalui beberapa lapisan tipuan. Dalam iterasi sebelumnya, kami menggunakan BCrypt; tetapi pindah ke PBKDF2 karena dibangun ke dalam kerangka .NET, sedangkan BCrypt akan meminta kami untuk memverifikasi suatu implementasi (bukan usaha kecil).

Kevin Montrose, 27 Mei 2011

(Tautan yang diperbarui di GitHub)

Sunting: Arti diverifikasi dalam istilah kriptografi tampaknya tidak mudah dipahami, implementasi yang terverifikasi berarti telah terbukti secara kriptografi untuk diimplementasikan tanpa kesalahan. Biaya ini dapat dengan mudah mencapai $ 20.000 atau lebih tinggi. Saya ingat ini ketika saya sedang melakukan penelitian tentang OpenSSL dan membaca di mana mereka menyatakan mereka belum menyelesaikan seluruh proses verifikasi tetapi jika Anda perlu diverifikasi sepenuhnya bahwa mereka dapat mengarahkan Anda ke jalan yang benar untuk itu dan menyebutkan biaya yang terkait. Persyaratan pemerintah tertentu termasuk mandat untuk algoritma enkripsi yang diverifikasi.

Implementasi bcrypt di .NET belum diverifikasi. Menggunakan implementasi enkripsi yang tidak diverifikasi, Anda tidak dapat benar-benar yakin bahwa tidak ada kesalahan berbahaya yang disengaja di dalamnya seperti memungkinkan pintu belakang ke apa yang dienkripsi atau kesalahan implementasi yang tidak disengaja yang menghasilkan data yang tidak aman secara kriptografis.

Sunting 2014: Bagi siapa pun yang mempertanyakan pentingnya menggunakan algoritma cryptopgraphical terverifikasi, lihatlah kehancuran yang disebabkan oleh peretasan yang dilakukan di OpenSSL. Itu adalah biaya menggunakan implementasi yang tidak diverifikasi. Aman .... sampai Anda mengetahui bahwa ada orang yang bisa membaca seluruh isi memori server Anda.

Penulis perubahan yang memperkenalkan Heartbleed, Robin Seggelmann, menyatakan bahwa ia "melewatkan validasi variabel yang berisi panjang" dan menyangkal niat untuk mengajukan implementasi yang cacat. Setelah pengungkapan Heartbleed, Seggelmann menyarankan untuk fokus pada aspek kedua, yang menyatakan bahwa OpenSSL tidak ditinjau oleh cukup banyak orang.

Ini adalah definisi dari implementasi yang tidak diverifikasi. Bahkan cacat terkecil dapat mengakibatkan melumpuhkan seluruh keamanan.

Sunting 2015: Bahasa berbasis rekomendasi yang dihapus dan diganti dengan absolut. Tertulis asli Kevin Montrose komentar untuk anak cucu.

Chris Marisic
sumber
25
Mengutip komentar yang ditautkan: "[kami] pindah ke PBKDF2 karena dibangun ke dalam kerangka .NET, sedangkan BCrypt akan meminta kami untuk memverifikasi suatu implementasi". Perhatikan bahwa komentar tidak mengatakan algoritme lebih baik, hanya saja SE Dev Team menganggap implementasi PBKDF2 bawaan lebih dipercaya daripada perpustakaan eksternal (yang, pada akhirnya, panggilan penilaian).
Piskvor meninggalkan gedung
3
@Piskvor saya memperbarui jawaban saya. Ini bukan tentang apa yang dianggap aman oleh tim SO, tetapi panggilan penilaian antara aman secara inheren terbukti atau mudah-mudahan aman. Yang terakhir ketika datang ke kriptografi tidak dapat diterima.
Chris Marisic
6
Saya bertanya-tanya bagaimana SO memigrasikan semua kata sandi hash bcrypt ke hash baru? Tidakkah mereka membutuhkan kata sandi mentah untuk hash menggunakan algoritma baru?
Dharmendar Kumar 'DK'
8
@ DK Saya bahkan tidak berpikir Anda harus meminta mereka untuk mereset kata sandi mereka. Pada login berikutnya (di mana mereka menyediakan kata sandi plaintext mereka) Anda dapat melakukannya saya percaya.
Matt Kocaj
12
Ini adalah saran yang buruk dan saya terkejut memiliki begitu banyak upvotes. Memverifikasi implementasi BCrypt dalam bahasa yang dikelola jauh, jauh lebih sepele daripada memverifikasi sesuatu seperti seluruh implementasi SSL dalam C. Heartbleed sama sekali tidak relevan; Anda akan lebih baik menyebutkan sesuatu seperti masalah paksaan jenis PHP dengan pemeriksaan kesetaraan hash. Plus sementara sebagian besar cocok dalam arti praktis, PBKDF2 adalah KDF, bukan algoritma hashing kata sandi, sedangkan BCrypt lebih cocok. Bagaimanapun, akan lebih masuk akal untuk menggunakan Argon2 akhir-akhir ini, yang mana ada pustaka C # yang teruji dengan baik
Polinomial