Необходимость скрывать соль для хеша

99

В работе у нас есть две конкурирующие теории солей. В продуктах, над которыми я работаю, используется что-то вроде имени пользователя или номера телефона для добавления хэша. По сути, то, что отличается для каждого пользователя, но легко доступно для нас. Другой продукт случайным образом генерирует соль для каждого пользователя и изменяется каждый раз, когда пользователь меняет пароль. Затем соль зашифровывается в базе данных.

У меня вопрос, а нужен ли второй подход? Я могу понять с чисто теоретической точки зрения, что это более безопасно, чем первый подход, но как насчет точки зрения практичности. Прямо сейчас, чтобы аутентифицировать пользователя, соль должна быть незашифрована и применена к информации для входа.

Поразмыслив над этим, я просто не вижу реального повышения безопасности от такого подхода. Изменение соли с учетной записи на учетную запись по-прежнему делает чрезвычайно трудным попытку кого-либо подобрать алгоритм хеширования, даже если злоумышленник знал, как быстро определить, что это было для каждой учетной записи. Это происходит при условии, что пароли достаточно надежны. (Очевидно, что найти правильный хеш для набора паролей, где все они состоят из двух цифр, значительно проще, чем найти правильный хеш для паролей, состоящих из 8 цифр). Я ошибаюсь в своей логике или что-то мне не хватает?

EDIT: Хорошо , так вот почему я думаю , что это действительно спорный вопрос , чтобы зашифровать соль. (дай мне знать, на правильном ли я пути).

В следующем объяснении мы предположим, что пароли всегда состоят из 8 символов, а соль - 5, и все пароли состоят из строчных букв (это просто упрощает математику).

Наличие разной соли для каждой записи означает, что я не могу использовать одну и ту же радужную таблицу (фактически, технически я мог бы, если бы у меня была таблица достаточного размера, но давайте пока проигнорируем это). Насколько я понимаю, это настоящий ключ к разгадке, потому что для взлома каждой учетной записи мне приходится изобретать колесо, так сказать, для каждой из них. Теперь, если я знаю, как применить правильную соль к паролю для генерации хеша, я бы сделал это, потому что соль действительно просто увеличивает длину / сложность хешированной фразы. Поэтому я бы сократил количество возможных комбинаций, которые мне нужно было бы сгенерировать, чтобы «знать», что у меня есть пароль + соль, с 13 ^ 26 до 8 ^ 26, потому что я знаю, в чем состоит соль. Теперь это упрощает, но по-прежнему очень сложно.

Итак, зашифруйте соль. Если я знаю, что соль зашифрована, я бы не стал пытаться сначала ее расшифровать (при условии, что я знаю, что она имеет достаточный уровень шифрования). Я бы проигнорировал это. Вместо того, чтобы пытаться выяснить, как его расшифровать, возвращаясь к предыдущему примеру, я бы просто создал большую радужную таблицу, содержащую все ключи для 13 ^ 26. Незнание, что соль определенно замедлит меня, но я не думаю, что это добавило бы монументальной задачи попытаться сначала взломать шифрование соли. Вот почему я не думаю, что оно того стоит. Мысли?

Вот ссылка, описывающая, как долго пароли продержатся при атаке методом грубой силы: http://www.lockdown.co.uk/?pg=combi

kemiller2002
источник
Хороший вопрос, Кевин, очень своевременный. Я не могу комментировать безопасность, но, безусловно, есть удар по производительности для всего этого шифрования и дешифрования.
DOK
Вам не нужно игнорировать таблицу радуги приличного размера - эта таблица также делает зашифрованное соль спорной , так как он может расшифровать соленый хэш и использовать снова , чтобы расшифровать исходный хэш. Хорошая новость в том, что на создание стола потребуются века.
tloach
Что меня понимает, так это то, что я не совсем уверен, что создание радужной таблицы такого размера займет так много времени. Это дурацкая идея, возьмите платформу распределенных вычислений, такую ​​как Kraken (на самом деле это вроде как), чтобы ее сгенерировать. Сколько времени это займет тогда?
kemiller2002,
3
@Kevin: SHA1 возвращает 40-символьную шестнадцатеричную строку, поэтому существует 40 ^ 16 возможных возвращаемых значений. Предполагая, что один компьютер может вычислять 1000 хэшей каждую секунду, я подсчитал, что 1000000 компьютеров потребуется около 10 миллиардов лет, чтобы сгенерировать радужную таблицу, способную определить строку такого размера.
tloach
+1 хороший вопрос и вы начитаны. Я думаю, что вы неправильно ответили на этот вопрос. Всегда должен быть секретом, потому что хэш нельзя взломать, пока он не будет получен. Вам следует прочитать про CWE-760 ( cwe.mitre.org/data/definitions/760.html )
ладья

Ответы:

45

Ответ здесь - спросить себя, от чего вы на самом деле пытаетесь защитить? Если у кого-то есть доступ к вашей базе данных, значит, у него есть доступ к зашифрованным солям, и, вероятно, он также имеет доступ к вашему коду. Что они могли расшифровать зашифрованные соли? Если это так, то шифрование в любом случае бесполезно. Соль действительно в том, чтобы сделать так, чтобы невозможно было сформировать радужную таблицу, чтобы взломать всю вашу базу паролей за один раз, если она будет взломана. С этой точки зрения, пока каждая соль уникальна, нет никакой разницы, потребуется атака грубой силой с вашими солями или зашифрованными солями для каждого пароля индивидуально.

говорить
источник
Вроде новичок в этих концепциях. Таким образом, это может показаться наивным вопросом, но не будет ли проще сформировать эту радужную таблицу, зная соль для каждого пароля, поскольку вы бы попробовали только одну комбинацию значения соли для каждого возможного пароля?
stdout
Таблица ранбоу из, скажем, 1000 часто используемых паролей сломает это почти с той же скоростью, что и простое хеширование. Единственный способ, которым это сработает, - это если вы предположите, что распределение ваших паролей будет единообразным ... а мы знаем, что это не так
DaWNFoRCe
100

Скрывать соль не нужно.

Для каждого хеша следует использовать разную соль. На практике этого легко добиться, получив 8 или более байтов из генератора случайных чисел криптографического качества.

Из моего предыдущего ответа :

Соль помогает предотвратить атаки по заранее вычисленному словарю.

Предположим, у злоумышленника есть список вероятных паролей. Он может хешировать каждый и сравнить его с хешем пароля своей жертвы и посмотреть, совпадает ли он. Если список большой, это может занять много времени. Он не хочет тратить так много времени на следующую цель, поэтому записывает результат в «словарь», где хеш указывает на соответствующий вход. Если список паролей очень и очень длинный, он может использовать такие приемы, как радужная таблица, чтобы сэкономить место.

Однако предположим, что его следующая цель подсолила свой пароль. Даже если злоумышленник знает, в чем заключается соль, его предварительно вычисленная таблица бесполезна - соль изменяет хэш, полученный в результате каждого пароля. Он должен повторно хешировать все пароли в своем списке, добавив к входу соль цели. Для каждой соли нужен свой словарь, и если используется достаточно солей, у злоумышленника не будет места для хранения словарей для всех. Торговое пространство для экономии времени больше не вариант; злоумышленник должен вернуться к хешированию каждого пароля в своем списке для каждой цели, которую он хочет атаковать.

Так что хранить соль в секрете не обязательно. Достаточно убедиться, что у злоумышленника нет предварительно вычисленного словаря, соответствующего этой конкретной соли.


Поразмыслив над этим еще немного, я понял, что обмануть себя, думая, что соль можно спрятать, опасно. Гораздо лучше предположить, что соль нельзя спрятать, и, несмотря на это, спроектировать систему так, чтобы она была безопасной. Я дам более подробное объяснение в другом ответе.


Однако недавние рекомендации NIST поощряют использование дополнительной секретной «соли» (я видел, как другие называли этот дополнительный секрет «перцем»). Одна дополнительная итерация вывода ключа может быть выполнена с использованием этого секрета в качестве соли. Вместо того, чтобы повышать устойчивость к атаке с предварительно вычисленным поиском, этот раунд защищает от подбора пароля, как и большое количество итераций в хорошей функции получения ключа. Этот секрет не имеет смысла, если хранится с хешированным паролем; он должен храниться в секрете, а это может быть сложно в большой базе данных пользователей.

Эриксон
источник
1
Скрыть соль необходимо, потому что хэш нельзя сломать, пока он не будет получен. Это связано с CWE-760 ( cwe.mitre.org/data/definitions/760.html )
ладья
28
@The Rook - Нет, вы неверно истолковали этот вопрос. Это относится к использованию предсказуемых солей. В нем ничего не говорится о сохранении соляного секрета. В самом деле, вы не можете сохранить солевой секрет без использования другого секрета ... в таком случае, почему бы вам не использовать второй секрет в качестве соли? Использование имени пользователя в качестве соли плохо, потому что вполне вероятно, что несколько систем используют одно и то же имя пользователя, что делает более целесообразным создание таблицы для этой конкретной соли. Лучше всего использовать случайные соли, но их не нужно держать в секрете.
erickson
См. Также: stackoverflow.com/questions/1645161/…
Jacco
1
@erickson, я думаю, вы тут путаете терминологию. Соли не препятствуют атакам по словарю, если они не скрыты. Многие соли хранятся открыто. И если вы знаете соль, ваша атака по словарю замедляется только на время, необходимое для добавления соли к вашему словарному термину :) Соли предотвращают поиск в таблице Rainbow .... что чертовски быстро. Если злоумышленник знает вашу соль, вы не защищены от атаки по словарю. Если злоумышленник не знает вашей соли, вы защищены от атаки по словарю, и он должен использовать атаку грубой силы.
Ultratrunks
4
@Ultratrunks Да, я разъяснил некоторые из своих ответов по этой теме, используя термин «атаки по заранее вычисленному словарю». Более общий, чем таблицы Rainbow, он относится к любой структуре, которая позволяет выполнять обратный поиск открытого текста, используя его хэш в качестве ключа. Независимо от того, какие термины вы выберете, my прямо объясняет, что соль предназначена для победы над таблицами Rainbow и аналогичными механизмами. Вы всегда должны предполагать, что злоумышленник знает соль. Если бы это было возможно сохранить в секрете, вам не нужно было бы хешировать пароль.
erickson
3

Я понимаю, что «соль» затрудняет взлом, но не пытается скрыть лишние данные. Если вы пытаетесь повысить безопасность, сделав соль «секретной», то вам действительно нужно больше битов в ваших ключах шифрования.

gbarry
источник
3

Второй подход ненамного безопаснее. Соли защищают пользователей от атак по словарю и атак с использованием радужных таблиц. Они усложняют амбициозному злоумышленнику взломать всю вашу систему, но по-прежнему уязвимы для атак, направленных на одного пользователя вашей системы. Если вы используете общедоступную информацию, например номер телефона, и злоумышленник узнает об этом , значит, вы сэкономили ему шаг в их атаке. Конечно, вопрос спорный, получит ли злоумышленник всю вашу базу данных, соли и все такое.

РЕДАКТИРОВАТЬ: после перечитывания этого ответа и некоторых комментариев мне приходит в голову, что некоторая путаница может быть связана с тем, что я сравниваю только два очень конкретных случая, представленных в вопросе: случайная соль vs. неслучайная соль. Вопрос о том, с помощью телефонного номера в виде соли является спорным , если злоумышленник получает всю базу данных, а не вопрос об использовании соли вообще.

Билл Ящерица
источник
Как они защищаются от словарных атак?
tloach
Заставляя злоумышленника создавать новый словарь для каждой комбинации пароль + соль. Без соли можно использовать один словарь для всей таблицы паролей.
Bill the Lizard
«Конечно, вопрос спорный, получит ли злоумышленник всю вашу базу данных, соли и все такое». Разве не поэтому зашифрована соль?
Патрик МакЭлхейни
1
@ Билл: Вы только что описали радужную таблицу. Атака по словарю - это когда я беру обычные слова и пытаюсь аутентифицироваться по ним. Это грубая сила с сильно сокращенным пространством для ответа. Никакой хэш не защищает от грубой силы.
tloach
Я никогда не слышал об этой практике, но я не эксперт по безопасности. Похоже, что шифрование уникальных солей добавит дополнительный уровень защиты от атак радужной таблицы.
Bill the Lizard
3

... что-то вроде имени пользователя или номера телефона для добавления хэша. ...

У меня вопрос, а нужен ли второй подход? Я могу понять с чисто теоретической точки зрения, что это более надежно, чем первый подход, но как насчет практической точки зрения?

С практической точки зрения соль - это деталь реализации. Если вы когда-нибудь измените способ сбора или хранения информации о пользователях - а имена пользователей и номера телефонов иногда меняются, если использовать ваши точные примеры, - вы, возможно, поставили под угрозу свою безопасность. Вы хотите, чтобы такое внешнее изменение вызвало гораздо более серьезные проблемы с безопасностью?

Требуется ли отмена требования о том, что у каждой учетной записи есть номер телефона, включать полную проверку безопасности, чтобы убедиться, что вы не открыли эти учетные записи с точки зрения безопасности?

Анон
источник
2
Не говоря уже о том, что если вы используете какой-то произвольный бит пользовательской информации, когда они изменяют эту информацию, вам нужно, чтобы они снова вводили свой пароль, чтобы вы могли снова зашифровать его с помощью новой соли.
Treborbob
3

Скрытая соль больше не соль. Это перец. В нем есть свое применение. Он отличается от соли.

Pepper - это секретный ключ, добавленный к паролю + соли, который превращает хэш в HMAC (код аутентификации сообщений на основе хэша). Хакер, имеющий доступ к выходным данным хэша и соли, теоретически может угадать ввод, который будет генерировать хэш (и, следовательно, пройти проверку в текстовом поле пароля) методом перебора. Добавляя перец, вы увеличиваете проблемное пространство криптографически случайным образом, делая проблему неразрешимой без серьезного оборудования.

Дополнительную информацию о перце можно найти здесь .

См. Также hmac .

Джон Ву
источник
2

Вот простой пример, показывающий, почему плохо иметь одну и ту же соль для каждого хэша.

Рассмотрим следующую таблицу

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

Случай 1, когда соль 1 совпадает с солью 2 Если Hash2 заменяется на Hash1, то пользователь 2 может войти в систему с паролем пользователя 1

Случай 2, когда соль 1 не совпадает с солью 2. Если Hash2 заменен на Hash1, то пользователь 2 не может войти в систему с паролем пользователя 1.

Чарльз Файга
источник
Мы не используем один и тот же хэш для каждой учетной записи, мы используем один и тот же тип информации для каждого хэша. Например, соль для учетной записи
телефонный
Я знаю, что это произойдет намного позже, но ... нельзя полагаться на соли для защиты от этого типа атак. Мы должны предположить, что злоумышленник знает все о системе аутентификации, кроме секрета (то есть пароля). Поэтому мы должны предположить, что злоумышленник знает: а) что мы используем в качестве соли (в большинстве случаев это хранится в той же базе данных и таблице в виде открытого текста) и б) как мы хэшируем с солью (т.е. добавляем, дважды хешируем, и т.д). Если у пользователя есть возможность переключать хэши, мы должны предположить, что они также могут переключать соль. Соли тут не помогут.
Дэйв Сатч
1

Есть две техники с разными целями:

  • «Соль» используется для того, чтобы два одинаковых пароля шифровались по-разному. Таким образом, злоумышленник не может эффективно использовать словарную атаку против всего списка зашифрованных паролей.

  • (Общий) «секрет» добавляется перед хешированием сообщения, чтобы злоумышленник не мог создавать свои собственные сообщения и принимать их.

Хавьер
источник
0

Я стараюсь скрыть соль. Я использую 10 бит соли, добавляя случайное число от 1 до 1024 в начало пароля перед его хешированием. Сравнивая пароль, введенный пользователем, с хешем, я перебираю от 1 до 1024 и пробую все возможные значения соли, пока не найду совпадение. Это занимает менее 1/10 секунды. Мне пришла в голову идея сделать это таким образом из файлов PHP password_hash и password_verify . В моем примере «стоимость» равна 10 за 10 кусочков соли. Или, как сказал другой пользователь, скрытая «соль» называется «перцем». В базе данных соль не зашифрована. Это грубое вытеснение. Это сделало бы радужную таблицу необходимой, чтобы перевернуть хэш в 1000 раз больше. Я использую sha256, потому что он быстрый, но все же считается безопасным.

Рассел Хэнкинс
источник
Итак, если мой пароль - «345678», а случайная соль, которую вы добавляете, оказывается, скажем, «12». Если кто-то вводит мой пароль «45678». Во многих отношениях это кажется неправильным.
Yurippenet
-1

На самом деле, это зависит от того, от какого типа атаки вы пытаетесь защитить свои данные.

Назначение уникальной соли для каждого пароля - предотвратить словарную атаку на всю базу паролей.

Да, шифрование уникальной соли для каждого пароля затруднит взлом индивидуального пароля, но вы должны взвесить, действительно ли это дает большую пользу. Если злоумышленник методом грубой силы обнаружит, что эта строка:

Marianne2ae85fb5d

хеши к хешу, хранящемуся в БД, неужели так сложно понять, какая часть является проходом, а какая - солью?

Лукас Оман
источник
2
Если кто-то переборщит с таким невозможным подобрать пароль, я бы сказал, что вы все равно забиты, потому что, очевидно, у них есть технология, о которой никто еще даже не подумал.
Instance Hunter