Artikel Coda Hale "Cara Aman Menyimpan Kata Sandi" mengklaim bahwa:
bcrypt memiliki garam bawaan untuk mencegah serangan tabel pelangi.
Dia mengutip makalah ini , yang mengatakan bahwa dalam implementasi OpenBSD tentang bcrypt
:
OpenBSD menghasilkan garam bcrypt 128-bit dari stream kunci arcfour (arc4random (3)), diunggulkan dengan data acak yang dikumpulkan kernel dari pengaturan waktu perangkat.
Saya tidak mengerti bagaimana ini bisa berhasil. Dalam konsepsi saya tentang garam:
- Itu harus berbeda untuk setiap kata sandi yang disimpan, sehingga tabel pelangi yang terpisah harus dihasilkan untuk masing-masing kata sandi
- Itu perlu disimpan di suatu tempat agar dapat diulang: ketika pengguna mencoba masuk, kami mencoba kata sandi mereka, mengulangi prosedur salt-and-hash yang sama seperti yang kami lakukan ketika kami awalnya menyimpan kata sandi mereka, dan membandingkan
Ketika saya menggunakan Devise (seorang manajer login Rails) dengan bcrypt, tidak ada kolom garam dalam database, jadi saya bingung. Jika garam itu acak dan tidak disimpan di mana pun, bagaimana kita dapat dengan andal mengulangi proses hashing?
Singkatnya, bagaimana bisa bcrypt memiliki garam bawaan ?
"OrpheanBeholderScryDoubt"
Saya percaya frasa itu seharusnya ditulis sebagai berikut:
The
bcrypt
utilitas itu sendiri tidak muncul untuk mempertahankan daftar garam. Sebaliknya, garam dihasilkan secara acak dan ditambahkan ke output fungsi sehingga mereka diingat kemudian (sesuai dengan implementasi Javabcrypt
). Dengan kata lain, "hash" yang dihasilkan olehbcrypt
bukan hanya hash. Sebaliknya, itu adalah hash dan garam yang digabungkan.sumber
Bcrypt
menambahkan garam acak "akd2! *", menghasilkan "fooakd2! *", yang di-hash dan disimpan. Kemudian, saya mencoba masuk dengan kata sandi "bar". Untuk melihat apakah saya benar, itu perlu hash "barakd2! *". Jika garam itu dibuat secara acak untuk memulai, bagaimana ia tahu bagaimana menambahkannya kembali ke "bar" sebelum hashing dan membandingkan?bcrypt
tahu cara mengekstrak garam kembali dari output yang dihasilkan (yang disimpan dalam database). Ketika tiba saatnya untuk mengotentikasi,bcrypt
pisahkan output asli menjadi komponen hash dan garamnya. Komponen garam diterapkan pada kata sandi masuk yang diketik oleh pengguna.Untuk membuat segalanya lebih jelas,
Arah Pendaftaran / Masuk ->
Kata sandi + garam dienkripsi dengan kunci yang dihasilkan dari: biaya, garam dan kata sandi. kami menyebutnya nilai terenkripsi
cipher text
. lalu kita lampirkan garam ke nilai ini dan mengodekannya menggunakan base64. melampirkan biaya untuk itu dan ini adalah string yang dihasilkan daribcrypt
:$2a$COST$BASE64
Nilai ini akhirnya disimpan.
Apa yang perlu dilakukan penyerang untuk menemukan kata sandi? (arah lain <-)
Jika penyerang mendapat kendali atas DB, penyerang akan dengan mudah memecahkan kode nilai base64, dan kemudian ia akan dapat melihat garam. garam bukanlah rahasia. meskipun itu acak. Maka dia akan perlu mendekripsi
cipher text
.Apa yang lebih penting: Tidak ada hashing dalam proses ini, bukan enkripsi mahal CPU - dekripsi. jadi tabel pelangi kurang relevan di sini.
sumber
Ini dari dokumentasi antarmuka PasswordEncoder dari Spring Security,
Yang berarti, seseorang harus mencocokkan rawPassword yang akan dimasukkan lagi oleh pengguna pada login berikutnya dan mencocokkannya dengan kata sandi yang disandikan Bcrypt yang disimpan dalam database selama login / registrasi sebelumnya.
sumber