Perlunya menyembunyikan garam untuk hash


99

Di tempat kerja kami memiliki dua teori yang bersaing untuk garam. Produk yang saya kerjakan menggunakan sesuatu seperti nama pengguna atau nomor telepon untuk mengasinkan hash. Pada dasarnya sesuatu yang berbeda untuk setiap pengguna tetapi tersedia untuk kami. Produk lain secara acak menghasilkan salt untuk setiap pengguna dan berubah setiap kali pengguna mengubah sandi. Salt kemudian dienkripsi dalam database.

Pertanyaan saya adalah apakah pendekatan kedua benar-benar diperlukan? Saya dapat memahami dari perspektif teoritis murni bahwa ini lebih aman daripada pendekatan pertama, tetapi bagaimana dari sudut pandang kepraktisan. Saat ini untuk mengautentikasi pengguna, garam harus tidak dienkripsi dan diterapkan ke informasi login.

Setelah memikirkannya, saya tidak melihat keuntungan keamanan yang nyata dari pendekatan ini. Mengubah salt dari akun ke akun, masih menyulitkan seseorang untuk mencoba memaksakan algoritme hashing meskipun penyerang mengetahui cara menentukan dengan cepat untuk setiap akun. Ini terjadi dengan asumsi bahwa kata sandi cukup kuat. (Jelas menemukan hash yang benar untuk satu set kata sandi yang semuanya terdiri dari dua digit jauh lebih mudah daripada menemukan hash kata sandi yang benar yang terdiri dari 8 digit). Apakah saya salah dalam logika saya, atau ada sesuatu yang saya lewatkan?

EDIT: Oke jadi inilah alasan mengapa saya pikir itu benar-benar diperdebatkan untuk mengenkripsi garam. (biar tahu apakah saya di jalur yang benar).

Untuk penjelasan berikut, kami akan berasumsi bahwa kata sandi selalu 8 karakter dan salt adalah 5 dan semua kata sandi terdiri dari huruf kecil (itu hanya membuat matematika lebih mudah).

Memiliki garam yang berbeda untuk setiap entri berarti saya tidak dapat menggunakan tabel pelangi yang sama (sebenarnya secara teknis saya bisa jika saya memiliki ukuran yang cukup, tetapi mari kita abaikan itu untuk saat ini). Ini adalah kunci sebenarnya untuk garam dari apa yang saya pahami, karena untuk memecahkan setiap akun saya harus menemukan kembali roda sehingga untuk berbicara untuk masing-masing. Sekarang jika saya tahu cara menerapkan salt yang benar ke kata sandi untuk menghasilkan hash, saya akan melakukannya karena salt benar-benar hanya memperluas panjang / kompleksitas frasa hash. Jadi saya akan memotong jumlah kemungkinan kombinasi yang perlu saya hasilkan untuk "tahu" Saya memiliki kata sandi + garam dari 13 ^ 26 menjadi 8 ^ 26 karena saya tahu apa itu garam. Sekarang itu membuatnya lebih mudah, tetapi masih sangat sulit.

Jadi untuk mengenkripsi garam. Jika saya tahu garamnya dienkripsi, saya tidak akan mencoba dan mendekripsi (dengan asumsi saya tahu itu memiliki tingkat enkripsi yang cukup) terlebih dahulu. Saya akan mengabaikannya. Alih-alih mencoba mencari cara untuk mendekripsinya, kembali ke contoh sebelumnya saya hanya akan membuat tabel pelangi yang lebih besar yang berisi semua kunci untuk 13 ^ 26. Tidak mengetahui garam pasti akan memperlambat saya, tetapi saya tidak berpikir itu akan menambah tugas monumental untuk mencoba memecahkan enkripsi garam terlebih dahulu. Itu sebabnya saya tidak berpikir itu sepadan. Pikiran?

Berikut ini tautan yang menjelaskan berapa lama kata sandi akan bertahan di bawah serangan brute force: http://www.lockdown.co.uk/?pg=combi


Pertanyaan bagus, Kevin, sangat tepat waktu. Saya tidak dapat mengomentari keamanan, tetapi ada kinerja yang terpukul untuk semua enkripsi dan dekripsi ini, pasti.
DOK

Anda tidak perlu mengabaikan tabel pelangi dengan ukuran yang layak - tabel itu juga membuat perdebatan garam terenkripsi karena dapat mendekripsi hash asin dan digunakan lagi untuk mendekripsi hash asli. Kabar baiknya adalah meja itu mungkin membutuhkan waktu berabad-abad untuk dibuat.
tloach

Hal yang membuat saya tertarik adalah saya tidak sepenuhnya yakin tabel pelangi sebesar itu akan membutuhkan waktu lama untuk dibuat. Dia adalah ide yang aneh, menggunakan platform komputasi terdistribusi seperti Kraken (benar-benar seperti itu) untuk menghasilkannya. Berapa lama waktu yang dibutuhkan?
kemiller2002

3
@Kevin: SHA1 mengembalikan string hex 40 karakter, jadi ada 40 ^ 16 kemungkinan nilai kembalian. Dengan asumsi satu komputer dapat menghitung 1.000 hash setiap detik, saya menghitung 1.000.000 komputer akan membutuhkan waktu sekitar 10 miliar tahun untuk menghasilkan tabel pelangi yang mampu menentukan string sebesar itu.
tloach

+1 pertanyaan bagus dan Anda banyak membaca. Saya rasa Anda salah menjawab pertanyaan ini. Itu harus selalu menjadi rahasia karena hash tidak dapat dipecahkan sampai diperoleh. Anda harus membaca tentang CWE-760 ( cwe.mitre.org/data/definitions/760.html )
benteng

Jawaban:


45

Jawabannya di sini adalah bertanya pada diri sendiri apa yang sebenarnya Anda coba lindungi? Jika seseorang memiliki akses ke database Anda, maka mereka memiliki akses ke garam terenkripsi, dan mereka mungkin juga memiliki akses ke kode Anda. Dengan semua itu, bisakah mereka mendekripsi garam yang dienkripsi? Jika demikian maka enkripsi itu tidak berguna. Garam benar-benar ada untuk membuatnya sehingga tidak mungkin membentuk tabel pelangi untuk memecahkan seluruh basis data kata sandi Anda sekaligus jika itu dibobol. Dari sudut pandang itu, selama setiap garam unik, tidak ada perbedaan, serangan brute force akan diperlukan dengan garam Anda atau garam terenkripsi untuk setiap kata sandi satu per satu.


Agak baru dalam konsep ini. Jadi, ini mungkin terlihat seperti pertanyaan yang naif tetapi bukankah akan lebih mudah untuk membentuk tabel pelangi itu dengan mengetahui salt untuk setiap kata sandi karena Anda hanya akan mencoba satu kombinasi untuk nilai salt untuk setiap kemungkinan kata sandi?
stdout

tabel ranbow dari katakanlah 1000 kata sandi yang umum digunakan akan memecahkan ini dengan kecepatan yang hampir sama dengan hanya melakukan hashing. Satu-satunya cara ini akan berhasil adalah jika Anda mengasumsikan distribusi kata sandi Anda seragam .. dan kami tahu itu tidak
DaWNFoRCe

100

Tidak perlu menyembunyikan garam.

Garam yang berbeda harus digunakan untuk setiap hash. Dalam praktiknya, ini mudah dicapai dengan mendapatkan 8 atau lebih byte dari generator nomor acak kualitas kriptografi.

Dari jawaban saya sebelumnya :

Salt membantu menggagalkan serangan kamus yang sudah dihitung sebelumnya.

Misalkan penyerang memiliki daftar kemungkinan kata sandi. Dia dapat mencirikan masing-masing dan membandingkannya dengan hash kata sandi korbannya, dan melihat apakah cocok. Jika daftarnya besar, ini bisa memakan waktu lama. Dia tidak ingin menghabiskan banyak waktu untuk target berikutnya, jadi dia mencatat hasilnya di "kamus" di mana hash menunjuk ke input yang sesuai. Jika daftar kata sandi sangat, sangat panjang, dia dapat menggunakan teknik seperti Tabel Pelangi untuk menghemat ruang.

Namun, misalkan target berikutnya mengasinkan kata sandi mereka. Bahkan jika penyerang mengetahui apa itu salt, tabel yang telah dihitung sebelumnya tidak ada gunanya — salt mengubah hash yang dihasilkan dari setiap sandi. Dia harus mencirikan ulang semua kata sandi dalam daftarnya, membubuhkan garam target ke masukan. Setiap garam yang berbeda membutuhkan kamus yang berbeda, dan jika garam yang digunakan cukup, penyerang tidak akan memiliki ruang untuk menyimpan kamus untuk semuanya. Ruang perdagangan untuk menghemat waktu tidak lagi menjadi pilihan; penyerang harus kembali melakukan hashing pada setiap sandi di daftarnya untuk setiap target yang ingin diserang.

Jadi, garam tidak perlu dirahasiakan. Memastikan bahwa penyerang tidak memiliki kamus yang dihitung sebelumnya yang sesuai dengan salt tertentu sudah cukup.


Setelah memikirkan hal ini lebih dalam, saya menyadari bahwa membodohi diri sendiri dengan berpikir bahwa garam dapat disembunyikan itu berbahaya. Jauh lebih baik untuk mengasumsikan garam tidak dapat disembunyikan, dan merancang sistem agar aman meskipun demikian. Penjelasan lebih detail saya berikan di jawaban lain.


Namun, rekomendasi terbaru dari NIST mendorong penggunaan "garam" rahasia tambahan (saya pernah melihat orang lain menyebut rahasia tambahan ini "merica"). Satu iterasi tambahan dari turunan kunci dapat dilakukan dengan menggunakan rahasia ini sebagai garam. Alih-alih meningkatkan kekuatan terhadap serangan pencarian yang telah dihitung sebelumnya, putaran ini melindungi dari tebakan kata sandi, seperti halnya sejumlah besar iterasi dalam fungsi derivasi kunci yang baik. Rahasia ini tidak ada gunanya jika disimpan dengan kata sandi berciri; itu harus dikelola sebagai rahasia, dan itu mungkin sulit dilakukan dalam database pengguna yang besar.


1
Menyembunyikan garam diperlukan karena hash tidak dapat dipecahkan sampai diperoleh. Ini terkait dengan CWE-760 ( cwe.mitre.org/data/definitions/760.html )
benteng

28
@ The Rook - Tidak, Anda salah menafsirkan masalah itu. Ini mengacu pada penggunaan garam yang dapat diprediksi. Itu tidak mengatakan apa-apa tentang menjaga rahasia garam. Memang, Anda tidak dapat benar-benar menjaga rahasia garam tanpa menggunakan rahasia lain ... dalam hal ini, mengapa Anda tidak menggunakan rahasia kedua sebagai garam? Menggunakan nama pengguna sebagai garam itu buruk karena kemungkinan beberapa sistem berbagi nama pengguna yang sama, sehingga lebih bermanfaat untuk membuat tabel untuk garam khusus tersebut. Garam acak adalah yang terbaik, tetapi tidak perlu dirahasiakan.
erickson


1
@erickson, saya pikir Anda mencampurkan terminologi di sini. Garam tidak menghalangi serangan kamus kecuali jika disembunyikan. Banyak garam disimpan secara terbuka. Dan jika Anda tahu garamnya, serangan kamus Anda hanya diperlambat dengan waktu yang dibutuhkan untuk menambahkan garam ke istilah kamus Anda :) Garam mencegah pencarian tabel Rainbow .... yang sangat cepat. Jika penyerang mengetahui garam Anda, Anda tidak terlindungi dari serangan kamus. Jika penyerang tidak mengetahui salt Anda, Anda dilindungi dari serangan kamus dan mereka harus menggunakan serangan brute force.
Ultratrunks

4
@Ultratrunks Ya, saya telah mengklarifikasi beberapa jawaban saya tentang topik ini, menggunakan istilah "serangan kamus yang telah dihitung sebelumnya". Lebih umum daripada tabel Rainbow, ini mengacu pada struktur apa pun yang memungkinkan pencarian terbalik dari teks biasa menggunakan hash sebagai kuncinya. Terlepas dari istilah yang Anda pilih, saya menjelaskan secara eksplisit bahwa garam dimaksudkan untuk mengalahkan tabel Pelangi dan mekanisme serupa. Anda harus selalu menganggap penyerang tahu garam. Jika mungkin untuk merahasiakannya, Anda tidak perlu mencirikan kata sandi.
erickson

3

Pemahaman saya tentang "garam" adalah bahwa hal itu membuat pemecahan lebih sulit, tetapi tidak mencoba menyembunyikan data tambahan. Jika Anda mencoba mendapatkan keamanan lebih dengan menjadikan salt "rahasia", Anda sebenarnya hanya ingin lebih banyak bit dalam kunci enkripsi Anda.


3

Pendekatan kedua hanya sedikit lebih aman. Garam melindungi pengguna dari serangan kamus dan serangan meja pelangi. Mereka mempersulit penyerang yang ambisius untuk menyusupi seluruh sistem Anda, tetapi masih rentan terhadap serangan yang difokuskan pada satu pengguna sistem Anda. Jika Anda menggunakan informasi yang tersedia untuk umum, seperti nomor telepon, dan penyerang mengetahui hal ini , Anda telah menyelamatkan mereka selangkah dalam serangan mereka. Tentu saja pertanyaannya diperdebatkan jika penyerang mendapatkan seluruh database Anda, garam dan semuanya.

EDIT: Setelah membaca ulang jawaban ini dan beberapa komentar, saya menyadari bahwa beberapa kebingungan mungkin disebabkan oleh fakta bahwa saya hanya membandingkan dua kasus yang sangat spesifik yang disajikan dalam pertanyaan: garam acak vs. garam non-acak. Pertanyaan tentang menggunakan nomor telepon sebagai salt diperdebatkan jika penyerang mendapatkan seluruh database Anda, bukan pertanyaan tentang penggunaan salt sama sekali.


Bagaimana mereka melindungi dari serangan kamus?
tloach

Dengan memaksa penyerang membuat kamus baru untuk setiap kombinasi kata sandi + garam. Tanpa salt, satu kamus dapat digunakan untuk seluruh tabel kata sandi Anda.
Bill the Lizard

"Tentu saja pertanyaannya diperdebatkan jika penyerang mendapatkan seluruh database Anda, garam dan semuanya." Bukankah itu sebabnya garam dienkripsi?
Patrick McElhaney

1
@Bill: Anda baru saja menjelaskan tabel pelangi. Serangan kamus adalah saat saya mengambil kata-kata normal dan mencoba mengautentikasi dengan kata-kata itu. Ini adalah kekerasan dengan ruang jawaban yang sangat berkurang. Tidak ada pertahanan hash melawan kekerasan.
tloach

Saya belum pernah mendengar tentang praktik ini, tetapi saya bukan pakar keamanan. Sepertinya mengenkripsi garam unik akan menambah lapisan perlindungan ekstra terhadap serangan tabel pelangi.
Bill the Lizard

3

... Sesuatu seperti nama pengguna atau nomor telepon untuk mengasinkan hash. ...

Pertanyaan saya adalah apakah pendekatan kedua benar-benar diperlukan? Saya dapat memahami dari perspektif teoritis murni bahwa ini lebih aman daripada pendekatan pertama, tetapi bagaimana dengan dari sudut pandang kepraktisan?

Dari sudut pandang praktis, garam adalah detail implementasi. Jika Anda pernah mengubah cara informasi pengguna dikumpulkan atau dikelola - dan nama pengguna dan nomor telepon terkadang berubah, untuk menggunakan contoh persis Anda - maka Anda mungkin telah membahayakan keamanan Anda. Apakah Anda ingin perubahan yang menghadap ke luar memiliki masalah keamanan yang jauh lebih dalam?

Apakah menghentikan persyaratan bahwa setiap akun memiliki nomor telepon perlu melibatkan tinjauan keamanan lengkap untuk memastikan Anda tidak membuka akun tersebut untuk gangguan keamanan?


2
Belum lagi jika Anda menggunakan beberapa bit informasi pengguna yang sewenang-wenang, ketika mereka mengubah informasi itu Anda membutuhkan mereka untuk memasukkan kata sandi mereka lagi sehingga Anda dapat mengenkripsinya lagi dengan salt baru.
Treborbob

3

Garam yang tersembunyi bukan lagi garam. Ini merica. Itu ada gunanya. Ini berbeda dengan garam.

Pepper adalah kunci rahasia yang ditambahkan ke password + salt yang membuat hash menjadi HMAC (Hash Based Message Authentication Code). Seorang peretas dengan akses ke keluaran hash dan salt secara teoritis dapat memaksa secara kasar menebak masukan yang akan menghasilkan hash (dan karena itu lolos validasi di kotak teks kata sandi). Dengan menambahkan lada, Anda menambah ruang masalah dengan cara acak secara kriptografis, membuat masalah menjadi tidak terselesaikan tanpa perangkat keras yang serius.

Untuk informasi lebih lanjut tentang lada, lihat di sini .

Lihat juga hmac .


2

Berikut adalah contoh sederhana yang menunjukkan mengapa tidak baik menggunakan garam yang sama untuk setiap hash

Perhatikan tabel berikut

UserId  UserName,   Password
     1  Fred       Hash1 =  Sha(Salt1+Password1)    
     2  Ted        Hash2 =  Sha(Salt2+Password2)    

Kasus 1 ketika garam 1 sama dengan garam2 Jika Hash2 diganti dengan Hash1 maka pengguna 2 dapat masuk dengan kata sandi pengguna 1

Kasus 2 ketika garam 1 tidak sama dengan garam2 Jika Hash2 diganti dengan Hash1 maka pengguna2 tidak dapat masuk dengan pengguna 1 kata sandi.


Kami tidak menggunakan hash yang sama untuk setiap akun, kami menggunakan jenis informasi yang sama untuk setiap hash. Misalnya, garam untuk akun adalah nomor
telepon

Aku tahu ini lama sekali, tapi ... kamu tidak bisa mengandalkan garam untuk melindungi dari jenis serangan ini. Kita harus berasumsi daripada seorang penyerang tahu segalanya tentang sistem otentikasi selain rahasia (mis. Kata sandi). Oleh karena itu kita harus berasumsi bahwa penyerang mengetahui a) apa yang kita gunakan sebagai salt (seringkali ini disimpan dalam database & tabel yang sama dalam plaintext) dan b) bagaimana kita melakukan hashing dengan salt (yaitu menambahkan, melakukan hashing-dua kali, dll). Jika pengguna memiliki kemampuan untuk mengganti hash maka kita harus berasumsi bahwa mereka juga dapat mengganti garam. Garam tidak akan membantu di sini.
Dave Satch

1

Ada dua teknik, dengan tujuan berbeda:

  • "Salt" digunakan untuk membuat dua sandi yang sama dienkripsi secara berbeda. Dengan cara ini, penyusup tidak dapat secara efisien menggunakan serangan kamus terhadap seluruh daftar kata sandi terenkripsi.

  • "Rahasia" (bersama) ditambahkan sebelum melakukan hashing pada pesan, sehingga penyusup tidak dapat membuat pesannya sendiri dan menerimanya.


0

Saya cenderung menyembunyikan garam. Saya menggunakan 10 bit salt dengan memasukkan nomor acak dari 1 hingga 1024 ke awal kata sandi sebelum melakukan hashing. Saat membandingkan kata sandi yang dimasukkan pengguna dengan hash, saya mengulang dari 1 hingga 1024 dan mencoba setiap kemungkinan nilai salt hingga saya menemukan kecocokan. Ini membutuhkan waktu kurang dari 1/10 detik. Saya mendapat ide untuk melakukannya dengan cara ini dari PHP password_hash dan password_verify . Dalam contoh saya, "biaya" adalah 10 untuk 10 bit garam. Atau dari apa yang dikatakan pengguna lain, "garam" yang tersembunyi disebut "merica". Salt tidak dienkripsi dalam database. Ini dipaksa keluar. Ini akan membuat tabel pelangi diperlukan untuk membalikkan hash 1000 kali lebih besar. Saya menggunakan sha256 karena cepat, tetapi masih dianggap aman.


Jadi jika kata sandi saya adalah "345678" dan garam acak yang Anda tambahkan kebetulan, katakan, "12". Jika seseorang memasukkan "45678" sebagai sandi saya. Ini tampaknya salah dalam banyak hal.
Yurippenet

-1

Sungguh, itu tergantung dari jenis serangan apa yang Anda coba untuk melindungi data Anda.

Tujuan dari salt unik untuk setiap kata sandi adalah untuk mencegah serangan kamus terhadap seluruh database kata sandi.

Mengenkripsi salt unik untuk setiap kata sandi akan membuatnya lebih sulit untuk memecahkan kata sandi individual, ya, tetapi Anda harus mempertimbangkan apakah benar-benar ada banyak manfaatnya. Jika penyerang, dengan kekerasan, menemukan bahwa string ini:

Marianne2ae85fb5d

hashes to a hash disimpan di DB, apakah sulit untuk menentukan bagian mana yang lulus dan bagian mana yang merupakan garam?


2
Jika seseorang secara kasar memaksa kata sandi yang mustahil ditebak, saya akan mengatakan Anda disemprot, karena tampaknya mereka memiliki teknologi yang belum pernah terpikirkan oleh siapa pun.
Pemburu Instance
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.