Обновление: обратите внимание, я не спрашиваю, что такое соль, что такое радужная таблица, что такое словарная атака или какова цель соли. Я спрашиваю: если вы знаете, что пользователи используют соль и хэш, разве не легко вычислить их пароль?
Я понимаю этот процесс и сам реализую его в некоторых своих проектах.
s = random salt
storedPassword = sha1(password + s)
В базе данных вы храните:
username | hashed_password | salt
Каждая реализация соления, которую я видел, добавляет соль либо в конец пароля, либо в начало:
hashed_Password = sha1(s + password )
hashed_Password = sha1(password + s)
Следовательно, словарная атака со стороны хакера, который стоит его соли (ха-ха), просто запустит каждое ключевое слово против сохраненных солей в общих комбинациях, перечисленных выше.
Конечно, описанная выше реализация просто добавляет хакеру еще один шаг, не решая при этом основную проблему? Какие есть альтернативы, чтобы обойти эту проблему, или я неправильно понимаю проблему?
Единственное, что я могу придумать, - это иметь секретный алгоритм смешивания, который связывает соль и пароль вместе в случайном порядке или добавляет другие пользовательские поля в процесс хеширования, что означает, что хакер должен иметь доступ к базе данных И коду для привязки их, чтобы словарная атака оказалась плодотворной. (Обновление, как указано в комментариях, лучше предполагать, что хакер имеет доступ ко всей вашей информации, поэтому, вероятно, это не лучший вариант).
Позвольте мне привести пример того, как я предлагаю хакеру взломать базу данных пользователей со списком паролей и хэшей:
Данные из нашей взломанной базы:
RawPassword (not stored) | Hashed | Salt
--------------------------------------------------------
letmein WEFLS... WEFOJFOFO...
Общий словарь паролей:
Common Password
--------------
letmein
12345
...
Для каждой записи пользователя зацикливайте общие пароли и хешируйте их:
for each user in hacked_DB
salt = users_salt
hashed_pw = users_hashed_password
for each common_password
testhash = sha1(common_password + salt)
if testhash = hashed_pw then
//Match! Users password = common_password
//Lets visit the webpage and login now.
end if
next
next
Я надеюсь, что это лучше иллюстрирует мою точку зрения.
Учитывая 10 000 общих паролей и 10 000 пользовательских записей, нам нужно будет вычислить 100 000 000 хэшей, чтобы обнаружить как можно больше паролей пользователей. Это может занять несколько часов, но это не проблема.
Обновление теории взлома
Предположим, что мы - коррумпированный веб-хост, у которого есть доступ к базе данных хэшей и солей SHA1, а также к вашему алгоритму их смешивания. В базе данных 10 000 пользовательских записей.
Этот сайт утверждает, что может вычислять 2 300 000 000 хэшей SHA1 в секунду с использованием графического процессора. (В реальной ситуации, вероятно, будет медленнее, но пока мы будем использовать эту цифру).
(((95 ^ 4) / 2300000000) / 2) * 10000 = 177 секунд
Учитывая полный диапазон из 95 печатаемых символов ASCII с максимальной длиной 4 символа, разделенный на скорость вычисления (переменная), деленную на 2 (при условии, что среднее время на обнаружение пароля в среднем потребует 50% перестановок) для 10000 пользователям потребуется 177 секунд, чтобы разработать пароли всех пользователей, длина которых <= 4.
Немного подправим для реалистичности.
(((36 ^ 7) / 1000000000) / 2) * 10000 = 2 дня
Предполагая отсутствие чувствительности к регистру, с длиной пароля <= 7, только буквенно-цифровыми символами, потребуется 4 дня, чтобы решить для 10000 пользовательских записей, и я вдвое уменьшил скорость алгоритма, чтобы отразить накладные расходы и неидеальные обстоятельства.
Важно понимать, что это линейная атака методом грубой силы, все вычисления не зависят друг от друга, поэтому это идеальная задача для решения нескольких систем. (IE легко настроить 2 компьютера, запускающих атаку с разных сторон, что будет вдвое быстрее).
Учитывая случай рекурсивного хеширования пароля 1000 раз, чтобы сделать эту задачу более затратной в вычислительном отношении:
(((36 ^ 7) / 1 000 000 000) / 2) * 1000 секунд = 10,8839117 часов
Это представляет максимальную длину в 7 буквенно-цифровых символов при скорости выполнения менее половины от указанной цифры для одного пользователя .
Рекурсивное хеширование 1000 раз эффективно блокирует сплошную атаку, но целевые атаки на пользовательские данные по-прежнему уязвимы.
источник
Ответы:
Да, вам нужно всего 3 дня для sha1 (соль | пароль). Вот почему в хороших алгоритмах хранения паролей используется хеширование в 1000 итераций: вам понадобится 8 лет.
источник
Это не останавливает словарные атаки.
Что он делает, так это останавливает кого-то, кому удается получить копию вашего файла паролей, от использования радужной таблицы, чтобы выяснить, какие пароли из хешей.
В конце концов, это можно сделать с помощью грубой силы. Ответ на эту часть - заставить ваших пользователей не использовать слова из словаря в качестве паролей (например, минимальные требования по крайней мере одного числа или специального символа).
Обновление :
Я должен был упомянуть об этом раньше, но некоторые (большинство?) Систем паролей используют разные соли для каждого пароля, вероятно, хранящиеся вместе с самим паролем. Это делает бесполезным один-единственный радужный стол. Так работает библиотека шифрования UNIX , и современные UNIX-подобные ОС расширили эту библиотеку новыми алгоритмами хеширования.
Я точно знаю, что поддержка SHA-256 и SHA-512 была добавлена в более новых версиях GNU crypt.
источник
Если быть более точным, атака по словарю , то есть атака, при которой проверяются все слова в исчерпывающем списке, не становится «невозможной», но становится непрактичной : каждый бит соли удваивает объем памяти и требуемых вычислений .
Это отличается от атак по заранее вычисленному словарю, таких как атаки с использованием радужных таблиц, где не имеет значения, является ли соль секретной или нет.
Пример: с 64-битной солью (т.е. 8 байтов) вам необходимо проверить 2 64 дополнительных комбинации паролей в вашей атаке по словарю. Со словарем, содержащим 200 000 слов, вам придется составить
тесты в худшем случае - вместо 200000 тестов без соли.
Дополнительным преимуществом использования соли является то, что злоумышленник не может предварительно вычислить хэши паролей из своего словаря. Это просто заняло бы слишком много времени и / или места.
Обновить
Ваше обновление предполагает, что злоумышленник уже знает соль (или украл ее). Это, конечно, другая ситуация. Тем не менее, злоумышленник не может использовать заранее вычисленную радужную таблицу. Здесь очень важна скорость хеш-функции. Чтобы сделать атаку непрактичной, функция хеширования должна быть медленной. MD5 или SHA здесь не подходят, потому что они разработаны, чтобы быть быстрыми. Лучшими кандидатами для алгоритмов хеширования являются Blowfish или некоторые его варианты.
Обновление 2
Хорошее чтение по вопросу защиты хэшей паролей в целом (выходит далеко за рамки исходного вопроса, но все же интересно):
Следствие из статьи: используйте соленые хэши, созданные с помощью bcrypt (на основе Blowfish) или Eksblowfish, что позволяет вам использовать настраиваемое время установки для замедления хеширования.
источник
Словарь - это структура, в которой значения индексируются по ключам. В случае атаки по заранее вычисленному словарю каждый ключ является хешем, а соответствующее значение - паролем, результатом которого является хеш. Имея в руках предварительно вычисленный словарь, злоумышленник может «мгновенно» найти пароль, который даст необходимый хэш для входа в систему.
С солью пространство, необходимое для хранения словаря, быстро увеличивается ... настолько быстро, что попытки предварительно вычислить словарь паролей вскоре становятся бессмысленными.
Лучшие соли выбираются случайным образом из криптографического генератора случайных чисел. Восемь байтов - это практический размер, а более 16 байтов не имеют смысла.
Соль делает гораздо больше, чем просто «делает работу злоумышленника более раздражающей». Он устраняет целый класс атак - использование предварительно вычисленных словарей.
Другой элемент, необходимый для полной защиты паролей, - это «усиление ключа». Одного раунда SHA-1 недостаточно: безопасный алгоритм хеширования паролей должен быть очень медленным в вычислительном отношении.
Многие люди используют PBKDF2, функцию вывода ключей, которая тысячи раз передает результаты в хэш-функцию . Алгоритм «bcrypt» аналогичен, в нем используется медленный итерационный вывод ключей.
Когда операция хеширования выполняется очень медленно, заранее вычисленная таблица становится все более и более желательной для злоумышленника. Но настоящая соль побеждает такой подход.
Комментарии
Ниже приведены комментарии, которые я сделал по этому вопросу.
Без соли злоумышленник не использовал бы метод, продемонстрированный в «Обновлении 2». Он просто выполнял поиск в предварительно вычисленной таблице и получал пароль за время O (1) или O (log n) (n - количество возможных паролей). Соль мешает этому и заставляет его использовать подход O (n), показанный в «Обновлении 2».
После сокращения до O (n) атаки мы должны учитывать, сколько времени займет каждая попытка. Усиление ключа может привести к тому, что каждая попытка в цикле будет занимать целую секунду, а это означает, что время, необходимое для проверки 10 000 паролей на 10 000 пользователей, растянется от 3 дней до 3 лет … и всего с 10 000 паролями вы, вероятно, не взломаете ноль пароли в то время.
Вы должны учитывать, что злоумышленник будет использовать самые быстрые инструменты, которые он может, а не PHP, поэтому тысячи итераций, а не 100, будут хорошим параметром для усиления ключа. Вычисление хэша для одного пароля должно занимать большую долю секунды.
Усиление ключей является частью стандартных алгоритмов вывода ключей PBKDF1 и PBKDF2 из PKCS # 5, которые создают отличные алгоритмы обфускации паролей («производный ключ» - это «хэш»).
Многие пользователи StackOverflow ссылаются на эту статью, потому что это был ответ на сообщение Джеффа Этвуда об опасности радужных таблиц. Это не моя любимая статья, но эти концепции обсуждаются более подробно.
Конечно, вы предполагаете, что у злоумышленника есть все: соль, хеш, имя пользователя. Предположим, что злоумышленник - коррумпированный сотрудник хостинговой компании, который сбросил таблицу пользователей на вашем фан-сайте myprettypony.com. Он пытается восстановить эти пароли, потому что он собирается повернуться и посмотреть, не использовали ли ваши фанаты пони тот же пароль для своих учетных записей citibank.com.
С хорошо разработанной схемой пароля, это будет невозможно для этого парня , чтобы восстановить пароли.
источник
Дело в том, чтобы не допустить амортизации усилий атакующего.
Без соли единая таблица предварительно вычисленных записей хеш-паролей (например, MD5 всех буквенно-цифровых 5-символьных строк, которые легко найти в Интернете) может использоваться для каждого пользователя в любой базе данных в мире.
С учетом специфики сайта злоумышленник должен сам вычислить таблицу и затем использовать ее для всех пользователей сайта.
При использовании соли для каждого пользователя злоумышленник должен приложить усилия для каждого пользователя отдельно.
Конечно, это не очень помогает защитить действительно слабые пароли прямо из словаря, но защищает достаточно надежные пароли от такой амортизации.
источник
Также - еще один важный момент - использование соли, специфичной для ПОЛЬЗОВАТЕЛЯ, предотвращает обнаружение двух пользователей с одним и тем же паролем - их хэши будут совпадать. Вот почему во многих случаях хеш является хешем (соль + имя пользователя + пароль)
Если вы попытаетесь сохранить хэш в секрете, злоумышленник также не сможет его проверить.
Изменить - только что заметил, что основная мысль была сделана в комментарии выше.
источник
Соли реализованы для предотвращения атак радужной таблицы. Радужная таблица - это список предварительно рассчитанных хешей, что значительно упрощает преобразование хеша во фразу. Вы должны понимать, что соление неэффективно в качестве современного средства предотвращения взлома пароля, если у нас нет современного алгоритма хеширования.
Итак, допустим, мы работаем с SHA1, пользуясь преимуществами недавних эксплойтов, обнаруженных с помощью этого алгоритма, и допустим, что у нас есть компьютер, работающий со скоростью 1000000 хэшей в секунду, на обнаружение коллизии потребуется 5,3 миллиона миллионов миллионов лет , так что да, php может работать 300 в секунду, большой ууп, на самом деле не имеет значения. Причина, по которой мы солим, состоит в том, что если кто-то потрудился сгенерировать все распространенные словарные фразы (2 ^ 160 человек, добро пожаловать в эксплойты эпохи 2007 года).
Итак, вот настоящая база данных с двумя пользователями, которых я использую для тестирования и администрирования.
По сути, схема засолки - это ваш sha1 (время регистрации + имя пользователя). Скажите мне мой пароль, это настоящие пароли в производстве. Вы даже можете сидеть и составлять список слов на php. Неистовствовать.
Я не сумасшедший, я просто знаю, что это безопасно. Ради шутки, пароль теста -
test
.sha1(sha1(1281546174.065087 + test) + test) = 5872548f2abfef8cb729cac14bc979462798d023
Вам нужно будет генерировать всю таблицу радуги perpended с
27662aee8eee1cb5ab4917b09bdba31d091ab732
для всего этого пользователя. Это означает, что я могу позволить, чтобы все мои пароли не были скомпрометированы одной радужной таблицей, хакеру необходимо создать целую радужную таблицу для 27662aee8eee1cb5ab4917b09bdba31d091ab732 для тестирования и снова f3f7735311217529f2e020468004a2af5b3dee7. Вспомните 5,3 миллиона миллионов миллионов лет для всех хешей. Подумайте о размере хранения только 2 ^ 80 хэшей (это намного больше 20 йоттабайт ), этого не произойдет.Не путайте соление как средство создания хэша, который вы никогда не сможете декодировать, это средство предотвратить перевод всех ваших пользовательских паролей радужной таблицей . Это невозможно на таком уровне технологий.
источник
Идея атаки по словарю заключается в том, что вы берете хеш и находите пароль, на основе которого был вычислен этот хеш, без вычисления хеша. Теперь сделайте то же самое с солёным паролем - вы не можете.
Отсутствие соли делает поиск пароля таким же простым, как поиск в базе данных. Добавление соли заставляет злоумышленника вычислять хеши всех возможных паролей (даже для присоединения словаря это значительно увеличивает время атаки).
источник
Проще говоря: без соления каждый потенциальный пароль нужно хешировать только один раз, чтобы проверить его на соответствие каждому пользователю в любом месте «известной вселенной» (совокупность скомпрометированных баз данных), чей пароль хешируется с помощью того же алгоритма. При использовании соления, если количество возможных значений соли существенно превышает количество пользователей в «известной вселенной», каждый потенциальный пароль должен хешироваться отдельно для каждого пользователя, против которого он будет проверяться.
источник
Проще говоря, «соление» не предотвращает хеш-атаки (брутфорс или словарь), а только усложняет задачу; злоумышленнику нужно будет либо найти алгоритм соления (который при правильной реализации потребует большего количества итераций), либо перебором алгоритма, что, если оно не очень простое, практически невозможно. Соление также почти полностью исключает возможность поиска в радужной таблице ...
источник
Соль значительно усложняет атаки на Rainbow-таблицы, так как значительно усложняет взлом одного хэша пароля. Представьте, что у вас есть ужасный пароль всего лишь с цифрой 1. Атака на радужную таблицу немедленно взломает его.
Теперь представьте, что каждый пароль в базе данных содержит длинное случайное значение из множества случайных символов. Теперь ваш паршивый пароль «1» хранится в базе данных как хэш из 1 плюс кучка случайных символов (соль), поэтому в этом примере радужная таблица должна иметь хэш для чего-то вроде: 1.
Итак, предположим, что ваша соль - что-то безопасное и случайное, скажем ()% ISLDGHASKLU ( % #% #, радужная таблица хакера должна иметь запись для 1 * ()% ISLDGHASKLU (*% #% #. Теперь используем радужную таблицу даже этот простой пароль больше не применим.
источник