Солярное поколение и программное обеспечение с открытым исходным кодом

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

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

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

Мысли?

Ответ 1

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

Ответ 2

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


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

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


Почему полезно использовать соление (или посев) хеша?

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

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


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

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

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


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

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

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

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

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

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

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


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

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

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


Полезные источники:
fooobar.com/questions/8379/...
Брюс Шнайер: Практическая криптография (книга)
Безопасность Matasano: достаточно с радужными таблицами
usenix.org: Используемая соль Unix с 1976 года
owasp.org: Зачем добавлять соль
openwall.com: Соли

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

Ответ 3

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

У этого есть некоторые хорошие эффекты. Во-первых, плохие парни не могут просто составить список ожидаемых паролей, таких как "Пароль1", помещать их в радужный стол и просматривать файл паролей, ищущий совпадения. Если у вас есть хорошая двухбайтовая соль, они должны генерировать 65 536 значений для каждого ожидаемого пароля, и это делает радужный стол намного менее практичным. Во-вторых, если вы можете сохранить соль у плохих парней, которые ищут ваш файл паролей, вам было намного сложнее рассчитать возможные значения. В-третьих, вы сделали невозможным, чтобы плохие парни определяли, использует ли данный человек один и тот же пароль на разных сайтах.

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

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

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

Ответ 4

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

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

Ответ 5

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

Мне нравится, как соль генерируется в 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 хорошо известен тем, что был сильным и нерушимым. Добавьте несколько измерений для создания самой соли, со случайным числом, ша и компонентом, специфичным для пользователя, у вас есть нерушимая безопасность!

Ответ 6

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

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

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