Salt Generation и программное обеспечение с открытым исходным кодом - PullRequest
70 голосов
/ 29 октября 2009

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

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

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

Мысли

Ответы [ 6 ]

226 голосов
/ 29 октября 2009

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


Что такое соль?

Соль - это случайный набор байтов фиксированной длины, который добавляется на вход алгоритма хеширования.


Почему засолка (или посев) полезна для хэша?

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

  1. Соление значительно увеличивает сложность / стоимость заранее вычисленных атак (включая радужные таблицы )
  2. Salting гарантирует, что один и тот же пароль не приведет к тому же хешу. Это гарантирует, что вы не сможете определить, имеют ли два пользователя один и тот же пароль. И, , что еще важнее, , вы не можете определить, использует ли один и тот же человек один и тот же пароль в разных системах.
  3. Соль увеличивает сложность паролей, тем самым значительно снижая эффективность как Dictionary- так и Атаки на день рождения . (Это верно только в том случае, если соль хранится отдельно от хеша).
  4. Правильное посоление значительно увеличивает потребность в хранилище для предварительных вычислений, вплоть до того момента, когда они перестают быть практичными. (8-символьные чувствительные к регистру буквенно-цифровые пароли с 16-битной солью, хэшированные до 128-битного значения, занимают чуть меньше 200 эксабайт без радужного сокращения).


Соль не нужна, чтобы быть секретной.

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

Соль должна быть случайной для каждого экземпляра, в котором она используется. Это гарантирует, что атакующий должен атаковать каждый соленый хеш отдельно.
Если вы полагаетесь на то, что ваша соль (или алгоритм соления) является секретной, вы вводите области Безопасность через неизвестность (не будет работать). Скорее всего, вы не получаете дополнительной защиты от соляной тайны; Вы просто получаете теплое нечеткое чувство безопасности. Поэтому вместо того, чтобы сделать вашу систему более безопасной, она просто отвлекает вас от реальности.


Итак, почему соль должна быть случайной?

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

Соблазнительно попытаться извлечь соль из некоторых данных, которые «предположительно уникальны», таких как идентификатор пользователя, но такие схемы часто терпят неудачу из-за некоторых неприятных деталей:

  1. Если вы используете , например, идентификатор пользователя , некоторые плохие парни, атакующие отдельные системы, могут просто объединить свои ресурсы и создать предварительно вычисленные таблицы для идентификаторов пользователей от 1 до 50. Идентификатор пользователя уникален для всей системы , но не для всего мира .

  2. То же самое относится к имени пользователя : в системе Unix есть один «корень», но в мире много корней. Радужный стол для «корня» стоил бы усилий, поскольку его можно применять к миллионам систем. Хуже того, есть также много «бобов», и у многих нет обучения сисадминам: их пароли могут быть довольно слабыми.

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

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


В заключение:

Используйте случайную, равномерно распределенную соль с высокой энтропией. Используйте новую соль всякий раз, когда вы создаете новый пароль или меняете пароль. Храните соль вместе с хешированным паролем. Пользуйтесь большими солями (не менее 10 байтов, предпочтительно 16 или более).

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


Полезные источники:
stackoverflow.com: Неслучайная соль для хэшей паролей
Брюс Шнайер: Практическая криптография (книга)
Матасано Безопасность: Хватит с радужными столами
usenix.org: Используемая соль склепа Unix с 1976 года
owasp.org : Зачем добавлять соль
openwall.com : Соли

Отказ от ответственности:
Я не эксперт по безопасности. (Хотя этот ответ был рассмотрен Томас Порнин )
Если кто-то из специалистов по безопасности найдет что-то не так, пожалуйста, прокомментируйте или отредактируйте этот вики-ответ.

18 голосов
/ 29 октября 2009

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

7 голосов
/ 30 октября 2009

С тех пор, как Unix стал популярным, правильный способ сохранить пароль - добавить случайное значение (соль) и хэшировать его. Сохраните соль там, где вы сможете добраться до нее позже, но там, где вы надеетесь, плохие парни не получат ее.

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

Для этого вы генерируете случайную соль. Это должно генерировать каждое число в желаемом диапазоне с одинаковой вероятностью. Это не сложно; простой линейный конгруэнтный генератор случайных чисел подойдет.

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

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

1 голос
/ 29 октября 2009

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

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

0 голосов
/ 26 мая 2011

В случае настольного приложения, которое шифрует данные и отправляет их на удаленный сервер, как вы считаете, каждый раз использовать разные соли?

Используя PKCS # 5 с паролем пользователя, требуется соль для генерации ключа шифрования, для шифрования данных. Я знаю, что хранить жестко запрограммированную соль в настольном приложении не очень хорошая идея.

Если удаленный сервер НИКОГДА не должен знать пароль пользователя, возможно ли каждый раз использовать разные соли? Если пользователь использует настольное приложение на другом компьютере, как он сможет расшифровать данные на удаленном сервере, если у него нет ключа (он не задан жестко в программном обеспечении)?

0 голосов
/ 29 октября 2009

Используйте генератор случайных функций для генерации соли и сохраните ее в базе данных, сделайте соль по одному на строку и сохраните ее в базе данных.

Мне нравится, как соль генерируется в django-регистрации. Справка: http://bitbucket.org/ubernostrum/django-registration/src/tip/registration/models.py#cl-85

salt = sha_constructor(str(random.random())).hexdigest()[:5]
activation_key = sha_constructor(salt+user.username).hexdigest()
return self.create(user=user,
           activation_key=activation_key)

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

Sha сам по себе хорошо известен как сильный и нерушимый. Добавьте несколько измерений, чтобы создать саму соль, со случайным числом, ша и пользовательским компонентом, у вас есть нерушимая безопасность!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...