Является ли time () хорошей солью? - PullRequest
56 голосов
/ 13 февраля 2011

Я смотрю код, который сам не написал.Код пытается хэшировать пароль с SHA512 и использует только time() в качестве соли.time() слишком просто соль для этого или этот код безопасен?

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

  • соль должна отличаться для каждого пользователя, поэтому, если 2 пользователя регистрируются одновременно, их соли не будут уникальными.Это проблема, но не большая.
  • но соль не должна быть связана с пользователем, поэтому time () не является хорошей солью.
  • " Используйте случайную, равномерно распределенную, соль с высокой энтропией. " - Это полный рот, так какой код может генерировать random, evenly distributed, high entropy соль?

Хорошо, как насчет замены time () случайной строкой длиной 32 символа.Случайная строка может быть сгенерирована из цикла 32 раза для набора символов алфавита.Звучит хорошо?

Ответы [ 9 ]

83 голосов
/ 13 февраля 2011

Краткий ответ:

Нет, time() не очень хорошая соль.

Длинный ответ:

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

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

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

1025 *
*

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

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

  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 : Соли

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


Что касается того, что кажется хорошим источником вашей случайной соли
Также читайте: Какое наиболее безопасное начальное число для генерации случайных чисел?
При отсутствии выделенных аппаратных случайных генераторов наилучшим способом получения случайных данных является обращение к операционной системе (в Linux это называется /dev/random или /dev/urandom [у обоих есть свои преимущества и проблемы, выберите свой яд) ; в Windows звоните CryptGenRandom())

Если по какой-либо причине у вас нет доступа к вышеупомянутым источникам случайных чисел, в PHP вы можете использовать следующую функцию:
Из источника phpass v0.3

<?php
/**
 * Generate pseudo random bits
 * @copyright: public domain
 * @link http://www.openwall.com/phpass/
 * @param int $length number of bits to generate
 * @return string A string with the hexadecimal number
 * @note don't try to improve this, you will likely just ruin it
 */
function random_bits($entropy) {
    $entropy /= 8;
    $state = uniqid();
    $str = '';
    for ($i = 0; $i < $entropy; $i += 16) {
        $state = md5(microtime().$state);
        $str .= md5($state, true);
    }
    $str = unpack('H*', substr($str, 0, $entropy));
    // for some weird reason, on some machines 32 bits binary data comes out as 65! hex characters!?
    // so, added the substr
    return substr(str_pad($str[1], $entropy*2, '0'), 0, $entropy*2);
}
?>
2 голосов
/ 13 февраля 2011

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

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

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

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

В реальном мире хранение соли в базе данных (случайной или нет), вероятно, менее безопасно, чем использование постоянной соли и ее захоронение подальше отличные глаза в файле, недоступном через веб-браузер.Трудно угадать уникальную соль с высокой энтропией, но если вы разрешили вход в систему с любого сервера на MySql и установили пароль на «пароль», это на самом деле не имеет значения!Покажите, как легко взломать базу данных по сравнению с получением действительного имени входа на ваш сервер - что, возможно, труднее сделать дискретно, так как вы можете установить fail2ban и множество других средств наблюдения за векторами атаки в зависимости от вашей настройки.

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

Еще одна альтернативная рекомендация экспертов по безопасности - сохранить имя пользователя в отдельной базе данных (и, в идеале, другую технологию), пароль и ссылку между ними, используя UUID.Например, используйте MySQL и SQLite.Это означает, что обе базы данных должны быть взломаны (а также, поэтому, чтобы перейти к отдельной кроличьей норе ради примера, не следует хранить данные пользователя и номера кредитных карт в одной базе данных, так как одна из них бесполезна бездругое).

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

Убедитесь, что вы применяете сильныйпароли и имена пользователей, поэтому атаки по словарю будут неудачными;Мне известны словари для всех 6-буквенно-цифровых комбинаций записей имени пользователя и пароля для MD5, и я подозреваю, что есть больше, чем это доступно для всех видов алгоритмов.С появлением недорогих облачных и CPGPU-вычислений размер и сложность доступных словарей будет стремительно расти.

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

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

Я не эксперт по безопасности, но прочитал об этом столько, сколько смог. Тот факт, что на эту тему так много книг, показывает, насколько велик ответ на ваш вопрос.

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

Уязвимости веб-приложений: обнаружение, использование, предотвращение - ISBN-13: 978-1-59749-209-6

Предотвращение веб-атак с помощью Apache - ISBN-13: 978-0-321-32128-2

2 голосов
/ 13 февраля 2011

Обновлено

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

  • Отличается для каждого пользователя
  • достаточно долго (по крайней мере 8 буквенно-цифровых символов), чтобы сделать объединение соли и (потенциально слабого) пароля слишком длинным для атаки методом перебора.

time() значения не достаточно длинные, так как они имеют 10 символов, но только цифры.

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

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

1 голос
/ 14 февраля 2011

Нет, время () не очень хорошая соль

Лучше не изобретать велосипед, когда дело доходит до аутентификации, но ответить на ваш вопрос, нет . Проблема со временем ():

  • Это предсказуемо и соотносится с потенциально обнаруживаемыми вещами. Эти проблемы облегчают сопоставление различных хэшированных результатов.
  • Не очень много возможных значений. Поскольку старшие биты не меняются, это еще более узкая соль, чем кажется на первый взгляд.
  • Использование повторяет предыдущие ошибки. Если бы это приложение было первым , которое использовало бы time () как соль, по крайней мере для этого потребовалась бы новая атака.
1 голос
/ 13 февраля 2011

Да.
Похоже, что метка времени Unix, хранящаяся в пользовательской базе данных как поле «Член с», будет солидной солью.

Тем не менее, солевой вопрос является наиболее незначительным. Есть гораздо более важные вещи, на которые вы должны обратить внимание:

  1. Скорее всего, ни пароль, ни соль, ни алгоритм хеширования не будут самой слабой частью вашего сайта. Некоторая инъекция хромого файла или XSS или CSRF, безусловно, есть. Так что, не делайте из этого слишком большой сделки.
    Говорить об истинной случайной строке длиной 32 символа в типичном веб-приложении - все равно, что говорить о 32-дюймовой бронированной двери в деревянном сарае.

  2. Говоря о паролях, самая важная вещь сложность сложность пароля. При слабом пароле не требуется ни алгоритм солью, ни хеширование, даже супер-гениальный-невероятно-сложный. Помогите. Больно просить пользователей использовать сложный пароль, но без него все остальное становится дерьмом.
    Итак, вашей первой заботой должна быть сложность пароля. Требуется 12-16 символов другого регистра, включая цифры и знаки препинания.

  3. Что касается соли, Я не вижу пользы в использовании времени, поскольку вы должны хранить его вместе с другими пользовательскими данными. Лучше использовать электронную почту - она ​​достаточно случайная, и она у вас уже есть. Не забудьте перефразировать пароль, если пользователь меняет свою электронную почту. похоже, что unix timstamp станет достойной солью, не нужно использовать электронную почту или что-то еще.

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

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

Они заслуживают, без сомнения. Но со слабым паролем миссия. является. невозможно.

Если ваш пароль слабый, то соль не защитит его.

Хотя соль не так важна, чтобы тратить 10-килобайтный текст на тему.

0 голосов
/ 08 марта 2012

Нет!Никогда не используйте текущее время в качестве соли.Вы можете использовать что-то вроде «SecureRandom» в Java, чтобы генерировать случайную соль, которая является безопасной.Всегда используйте непредсказуемое случайное число в качестве соли.
Использование времени в качестве соли поможет вам удалить коллизии только до определенной степени (поскольку два пользователя могут одновременно использовать одни и те же пароли), но при этом сделать пароли восстанавливаемыми..

0 голосов
/ 13 февраля 2011

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

0 голосов
/ 13 февраля 2011

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

0 голосов
/ 13 февраля 2011

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

Достаточно ли защищено соление с именем пользователя + отметка времени? Так должно быть. Для взлома хэшей SHA512 обычно используются Rainbow Tables. Имя пользователя + метка времени должны быть солью, которая достаточно уникальна, поэтому в сети нет никакой Радужной Таблицы, которая содержит предварительно вычисленные хэши с паролями, которые подсолены таким образом.

...