Поскольку вопросы о хешах с засолкой возникают довольно регулярно, и, похоже, в этом вопросе есть некоторая путаница, я расширил этот ответ.
Что такое соль?
Соль - это случайный набор байтов фиксированной длины, который добавляется на вход алгоритма хеширования.
Почему засолка (или посев) полезна для хэша?
Добавление случайной соли в хеш гарантирует, что один и тот же пароль будет производить много разных хешей. Соль обычно хранится в базе данных вместе с результатом хэш-функции.
Соль хеша хороша по ряду причин:
- Соление значительно увеличивает сложность / стоимость заранее вычисленных атак (включая радужные таблицы )
- Salting гарантирует, что один и тот же пароль не приведет к тому же хешу.
Это гарантирует, что вы не сможете определить, имеют ли два пользователя один и тот же пароль. И, , что еще важнее, , вы не можете определить, использует ли один и тот же человек один и тот же пароль в разных системах.
- Соль увеличивает сложность паролей, тем самым значительно снижая эффективность как Dictionary- так и Атаки на день рождения . (Это верно только в том случае, если соль хранится отдельно от хеша).
- Правильное посоление значительно увеличивает потребность в хранилище для предварительных вычислений, вплоть до того момента, когда они перестают быть практичными. (8-символьные чувствительные к регистру буквенно-цифровые пароли с 16-битной солью, хэшированные до 128-битного значения, занимают чуть меньше 200 эксабайт без радужного сокращения).
Соль не нужна, чтобы быть секретной.
Соль - это не секретный ключ, а соль «работает», делая хеш-функцию специфичной для каждого экземпляра. С соленым хэшем не существует одна хеш-функция, а одна для каждого возможного значения соли. Это не позволяет атакующему атаковать хешированные пароли N менее чем в N раз больше стоимости атаки одного пароля. Это точка соли.
«Секретная соль» - это не соль, она называется «ключом», и это означает, что вы больше не вычисляете хеш, а код аутентификации сообщения (MAC). Вычисление MAC - сложная задача (гораздо сложнее, чем просто сложить ключ и значение в хэш-функцию), и это совсем другой вопрос.
Соль должна быть случайной для каждого экземпляра, в котором она используется. Это гарантирует, что атакующий должен атаковать каждый соленый хеш отдельно.
Если вы полагаетесь на то, что ваша соль (или алгоритм соления) является секретной, вы вводите области Безопасность через неизвестность (не будет работать). Скорее всего, вы не получаете дополнительной защиты от соляной тайны; Вы просто получаете теплое нечеткое чувство безопасности. Поэтому вместо того, чтобы сделать вашу систему более безопасной, она просто отвлекает вас от реальности.
Итак, почему соль должна быть случайной?
Технически, соль должна быть уникальной . Смысл в том, чтобы быть отличным для каждого хешированного пароля. Это означает по всему миру . Поскольку не существует центральной организации, которая распределяет уникальные соли по требованию, мы должны полагаться на следующую лучшую вещь - случайный отбор с непредсказуемым случайным генератором, предпочтительно в пределах соленого пространства, достаточно большого, чтобы сделать столкновения невозможными (два случая, использующие один и тот же соленость).
Соблазнительно попытаться извлечь соль из некоторых данных, которые «предположительно уникальны», таких как идентификатор пользователя, но такие схемы часто терпят неудачу из-за некоторых неприятных деталей:
Если вы используете , например, идентификатор пользователя , некоторые плохие парни, атакующие отдельные системы, могут просто объединить свои ресурсы и создать предварительно вычисленные таблицы для идентификаторов пользователей от 1 до 50. Идентификатор пользователя уникален для всей системы , но не для всего мира .
То же самое относится к имени пользователя : в системе Unix есть один «корень», но в мире много корней. Радужный стол для «корня» стоил бы усилий, поскольку его можно применять к миллионам систем. Хуже того, есть также много «бобов», и у многих нет обучения сисадминам: их пароли могут быть довольно слабыми.
Уникальность также временна. Иногда пользователи меняют свой пароль. Для каждого нового пароля необходимо выбрать новую соль . В противном случае злоумышленник может получить хэш старого пароля, а новый может попытаться атаковать оба одновременно.
Использование случайной соли, полученной из криптографически безопасного, непредсказуемого PRNG, может быть своего рода излишним, но по крайней мере предположительно защищает вас от всех этих опасностей. Речь идет не о том, чтобы помешать злоумышленнику узнать, что такое соль индивидуум , а о том, чтобы не дать им большую, жирную цель, которая будет использоваться для значительного числа потенциальных целей. Случайный выбор делает цели настолько тонкими, насколько это практически возможно.
В заключение:
Используйте случайную, равномерно распределенную соль с высокой энтропией. Используйте новую соль всякий раз, когда вы создаете новый пароль или меняете пароль. Храните соль вместе с хешированным паролем. Пользуйтесь большими солями (не менее 10 байтов, предпочтительно 16 или более).
Соль не превращает плохой пароль в хороший пароль. Это просто гарантирует, что злоумышленник, по крайней мере, заплатит цену атаки по словарю за каждый неверный пароль, который он взламывает.
Полезные источники:
stackoverflow.com: Неслучайная соль для хэшей паролей
Брюс Шнайер: Практическая криптография (книга)
Матасано Безопасность: Хватит с радужными столами
usenix.org: Используемая соль склепа Unix с 1976 года
owasp.org : Зачем добавлять соль
openwall.com : Соли
Отказ от ответственности:
Я не эксперт по безопасности. (Хотя этот ответ был рассмотрен Томас Порнин )
Если кто-то из специалистов по безопасности найдет что-то не так, пожалуйста, прокомментируйте или отредактируйте этот вики-ответ.