Является ли время() хорошей солью?

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

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

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

Итак, как насчет того, чтобы заменить time() на случайную строку 32 char long. Случайную строку можно было бы генерировать по циклу 32 раза по набору символов алфавита. Звучит это хорошо?

Ответ 1

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

Нет, time() не является хорошей солью.

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

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

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

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


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

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

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


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

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

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


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

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

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

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

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

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

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


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

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

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


Полезные источники:
fooobar.com/questions/8379/...
Брюс Шнайер: Практическая криптография (книга)
Безопасность Matasano: достаточно с таблицами Rainbow
usenix.org: Unix crypt использовали соль с 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

Обновление

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

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

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

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

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

Ответ 3

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ответ 4

Да.
Кажется, что временная метка unix, хранящаяся в пользовательской базе данных как поле "Member from", будет приличной солью.

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

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

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

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

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

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

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

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

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

Ответ 5

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

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

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

Ответ 6

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

Ответ 7

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

Ответ 8

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

Ответ 9

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

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