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



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



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



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



мысли?

813   6  

6 ответов:

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

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


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

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


почему соление (или посев) хэш полезно?

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

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


нет необходимости, чтобы соль была секретной.

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Comments

    Ничего не найдено.