Я смотрю на какой-то код, который я сам не написал. Код пытается хешировать пароль с SHA512 и использует только time()
как соль. Является ли time()
слишком простым солью для этого или этот код безопасен?
Спасибо за ответы и комментарии. Я подведу итог для новых читателей:
random, evenly distributed, high entropy
соль? Итак, как насчет того, чтобы заменить time () на случайную строку 32 char long. Случайную строку можно было бы генерировать по циклу 32 раза по набору символов алфавита. Это звучит хорошо?
Нет, time()
не является хорошей солью.
скопирован из моего ответа на Salt Generation и с открытым исходным кодом
Что такое соль?
Соль представляет собой случайное множество байтов фиксированной длины, которое добавляется во вход хеш-алгоритма.
Почему полезно использовать соление (или посев) хеша?
Добавление случайной соли в хэш гарантирует, что один и тот же пароль будет генерировать множество разных хэшей. Соль обычно хранится в базе данных вместе с результатом хэш-функции. Солить хэш хорош по ряду причин:
- Соление значительно увеличивает трудности / затраты на предопределенные атаки (включая радужные столы )
- Соление гарантирует, что один и тот же пароль не приведет к такому же хэшу. Это гарантирует, что вы не можете определить, имеют ли два пользователя одинаковый пароль. И, что еще более важно , вы не можете определить, использует ли тот же самый пароль в разных системах.
Солирование увеличивает сложность паролей, тем самым значительно снижая эффективностьатакикаксловаря, такидня рождения.(Это справедливо только в том случае, если соль хранится отдельно от хеша).- Правильное засоление значительно увеличивает потребность в хранении для предвыборных атак, вплоть до того момента, когда они больше не практичны. (8 символов с буквенным алфавитом с 16-битной солью, хэшированные до 128-битного значения, занимают чуть менее 200 экзабайт без уменьшения радуги).
Не нужно, чтобы соль была секретной.
Соль не является секретным ключом, а соль «работает», делая хеш-функцию специфичной для каждого экземпляра. С соленым хешем не существует одной функции хэша, а одна для любого возможного значения соли. Это предотвращает атакующий атакующих хэшированных паролей менее чем в N раз больше, чем при атаке одного пароля. Это точка соли.
«Тайная соль» не соль, она называется «ключом», а это означает, что вы больше не используете хэш, а код аутентификации сообщения (MAC). Вычислить MAC – это сложный бизнес (намного сложнее, чем просто пощелкать ключ и значение в хэш-функцию), и это совсем другой предмет.Соль должна быть случайной для каждого экземпляра, в котором она используется. Это гарантирует, что атакующий должен атаковать каждый соленый хэш отдельно.
Если вы полагаетесь на свою секретную соль (или алгоритм соления), вы вводите сферы безопасности через Obscurity (не будет работать). Скорее всего, вы не получаете дополнительной защиты от соляной секретности; вы просто получаете теплое нечеткое чувство безопасности. Поэтому вместо того, чтобы сделать вашу систему более безопасной, она просто отвлекает вас от реальности.Итак, почему соль должна быть случайной?
Технически соль должна быть уникальной . Точка соли должна отличаться для каждого хешированного пароля. Это подразумевается во всем мире . Поскольку нет центральной организации, которая по мере необходимости распределяет уникальные соли, мы должны опираться на следующее лучшее, что представляет собой случайный выбор с непредсказуемым случайным генератором, предпочтительно в солевом пространстве, достаточно большом, чтобы сделать столкновения невероятными (два экземпляра, использующих один и тот же соль).
Заманчиво пытаться получить соль из некоторых данных, которые «предположительно уникальны», такие как идентификатор пользователя, но такие схемы часто терпят неудачу из-за некоторых неприятных деталей:
Если вы используете, например, идентификатор пользователя , некоторые плохие парни, атакующие разные системы, могут просто объединить свои ресурсы и создать предварительно вычисляемые таблицы для идентификаторов пользователей с 1 по 50. Идентификатор пользователя уникален в общесистемной, но не во всем мире .
То же самое относится к имени пользователя : в системе Unix есть один «корень», но в мире есть много корней. Радужный стол для «корня» будет стоить усилий, поскольку он может применяться к миллионам систем. Хуже того, там также много «боб», и у многих нет тренировки сисадмина: их пароли могут быть довольно слабыми.
Уникальность также временна. Иногда пользователи меняют свой пароль. Для каждого нового пароля необходимо выбрать новую соль . В противном случае атакующий получил хэш старого пароля и хэш нового может попытаться атаковать одновременно.
Использование случайной соли, полученной из криптографически безопасного, непредсказуемого PRNG, может быть чем-то вроде излишнего, но, по крайней мере, это защищает вас от всех этих опасностей. Речь идет не о том, чтобы злоумышленник не знал, что такое отдельная соль, а о том, чтобы не дать им большую, тучную цель, которая будет использоваться на значительном числе потенциальных целей. Случайный выбор делает цели такими же тонкими, насколько это практично.
В заключение:
Используйте случайную, равномерно распределенную соль с высокой энтропией. Используйте новую соль при создании нового пароля или изменении пароля. Храните соль вместе с хешированным паролем. Побалуйте большие соли (не менее 10 байт, предпочтительно 16 или более).
Соль не превращает плохой пароль в хороший пароль. Он просто гарантирует, что злоумышленник по крайней мере заплатит цену атаки на словарь за каждый неверный пароль, который он сломает.
Полезные источники:
stackoverflow.com: неслучайная соль для хэшей паролей
Брюс Шнайер: Практическая криптография (книга)
Безопасность Matasano: достаточно с таблицами Rainbow
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); } ?>
обновленный
Это не очень хорошая соль, но, вероятно, достаточно хорошая, чтобы победить всех, кроме самых решительных и находчивых нападавших. Требования к хорошей соли:
time()
не достаточно длинны, так как они имеют 10 символов, но только цифры.
Кроме того, иногда два пользователя могут получать одинаковое значение, когда они создаются в течение одной секунды. Но это только проблема, если у вас есть ситуации, когда многие пользователи автоматически создаются в течение одной секунды.
В любом случае, гораздо важнее, чем идеальная соль, использует хорошую хэш-функцию, а SHA512 – одно из лучших, которое мы имеем сейчас.
Этот пост может зависнуть слишком далеко от вашего первоначального вопроса, но я надеюсь, что вы сочтете это полезным;
Безопасность заключается в повышении барьеров и препятствий; глубокой защиты. Не существует действительно безопасного решения хэширования, только те, которые трудно сломать. Это похоже на то, что в вашем доме есть охранная сигнализация и оконные замки – сделайте свой сайт менее привлекательным, чтобы проникнуть, чем кто-то другой.
Соль для алгоритма склепа – лишь небольшая часть проблемы безопасности. Единственная соль просто означает, что при попытке разбить пароль для нескольких пользователей есть еще одна вещь. Низкоэнтропийная соль (например, время сервера) делает ее немного сложнее, а соль с высокой энтропией делает ее еще сложнее. Какой из них использовать, и нужно ли вам беспокоиться о том, что вам нужно беспокоиться, в первую очередь зависит как от чувствительности данных, которые вы защищаете, так и от того, какие другие меры безопасности у вас есть. На сайте, который просто дает персонализированный прогноз погоды для выбранного города, очевидно, имеет менее чувствительные данные, чем тот, у которого есть домашний адрес, имя девушки матери, дата рождения и другая информация, которая может быть использована для целей идентификации.
Итак, вот втирание; высокая соль энтропии по-прежнему является плохой солью, если ее легко получить.
В реальном мире хранение соли в базе данных (случайный или нет), вероятно, менее безопасен, чем использование постоянной соли и захоронение ее от частных глаз в недоступном для доступа файле через веб-браузер. Хотя уникальной и высокой энтропийной соли сложнее догадаться, если вы разрешили корневой вход с любого сервера на 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
Лучше не заново изобретать колесо, когда речь заходит об аутентификации, но чтобы ответить на ваш вопрос, нет . Проблема со временем ():
Да.
Кажется, что временная метка unix, хранящаяся в пользовательской базе данных как поле «Member from», будет приличной солью.
Однако, вопрос соли является самым незначительным. Есть гораздо более важные вещи, на которые вы должны обратить внимание:
Скорее всего, это не пароль, а соль или алгоритм хеширования, который будет слабой частью вашего сайта. Например, некоторая хромая инъекция файла или XSS или CSRF. Поэтому не делайте слишком много.
Говоря об истинной случайной строке длиной 32 символа в типичном веб-приложении, речь идет о 32-дюймовой бронированной двери в деревянном сарае.
Говоря о паролях, самая важная вещь – сложность паролей. При слабом пароле никакая соль и алгоритм хеширования, даже сверхсовременный, невероятно жесткий, могут помочь. Это боль, чтобы попросить пользователей использовать сложный пароль, но без него все остальное становится куском дерьма.
Итак, ваша первая забота – сложность паролей. Требуется 12-16 символов различного случая, включая числа и пунктуацию.
Что касается соли, я не вижу никакой пользы в использовании времени, так как вы должны хранить его вместе с другими пользовательскими данными. Лучше используйте электронную почту – она достаточно случайна, и у вас ее уже есть. Не забудьте перефразировать пароль, если пользователь изменит свой адрес электронной почты. кажется, что unix timstamp будет приличной солью, не нужно использовать электронную почту или что-то еще.
Обновить
Как я вижу, многие люди все еще не могут понять.
Как этот парень из комментариев, говоря
Многие пользователи используют слабые пароли (мы должны их обучать или, по крайней мере, продолжать пытаться), но это не оправдание; они по-прежнему заслуживают хорошей безопасности
Они заслуживают, без сомнения. Но со слабым паролем миссия. является. невозможно.
Хотя соль не так важна, чтобы тратить 10-килобайтный текст на эту тему.
Соль используется для предотвращения радужных атак, нарушая совпадение между паролем и предварительно вычисленным хешем. Таким образом, основная задача для соли должна отличаться для каждой записи пользователя / пароля. Качество рандомизации соли не имеет большого значения, если соль различна для разных пользователей.
дата, когда участник присоединяется к форуму / веб-сайту, обычно имеет открытый доступ, который будет таким же, как и time (), поэтому делает вашу соль бесполезной.
Нет! Никогда не используйте текущее время в качестве соли. Вы можете использовать что-то вроде «SecureRandom» в java, чтобы создать случайную соль, которая является безопасной. Всегда используйте непредсказуемое случайное число в качестве соли.
Использование времени в качестве соли поможет вам удалять столкновения только в определенной степени (поскольку два пользователя могут одновременно использовать одни и те же пароли), но все же делают пароли восстанавливаемыми.
Имя пользователя должно быть достаточным и, возможно, отметкой времени регистрации, но вы должны хранить его где-то в базе данных. В любом случае каждое значение, которое вы используете для слияния хэша паролей, должно храниться в некотором роде, чтобы вы могли пересчитать хеш.
Достаточно ли солить с именем пользователя + отметка времени? Должен быть. Для взлома SHA512 Хэши обычно используются таблицы Rainbow. Имя пользователя + отметка времени должна быть солью, которая достаточно однозначна, поэтому в сети нет какой-либо таблицы Rainbow, которая содержит предварительно просчитанные хэши с паролями, которые соленые таким образом.