Как соль пароля помогает против атаки радужной таблицы?
У меня возникли проблемы с пониманием назначения соли для пароля. Насколько я понимаю, основное использование - это препятствовать атаке радуги. Тем не менее, методы, которые я видел, чтобы реализовать это, похоже, не усложняют проблему.
Я видел много уроков, предлагающих использовать соль следующим образом:
$hash = md5($salt.$password)
Причина в том, что хеш теперь отображается не на исходный пароль, а на комбинацию пароля и соли. Но скажи $salt=foo
а также $password=bar
а также $hash=3858f62230ac3c915f300c664312c63f
, Теперь кто-то с радужным столом может поменять хеш и ввести "foobar". Затем они могут попробовать все комбинации паролей (f, fo, foo, ... oobar, obar, bar, ar, ar). Для получения пароля может потребоваться еще несколько миллисекунд, но не более того.
Другое использование я видел в моей системе Linux. В / etc / shadow хешированные пароли хранятся вместе с солью. Например, соль "foo" и пароль от "bar" хэшируют это: $1$foo$te5SBM.7C25fFDu6bIRbX1
, Если хакер каким-то образом смог достать этот файл, я не вижу, для чего служит соль, так как обратный хеш te5SBM.7C25fFDu6bIRbX
как известно, содержит "foo".
Спасибо за любой свет, который может пролить на это любой.
РЕДАКТИРОВАТЬ: Спасибо за помощь. Подводя итог, что я понимаю, соль делает хешированный пароль более сложным, что значительно снижает вероятность его существования в предварительно вычисленной радужной таблице. То, что я неправильно понял раньше, было то, что я предполагал, что для ВСЕХ хэшей существует радужный стол.
10 ответов
Публичная соль не усложнит атаки по словарю при взломе одного пароля. Как вы указали, злоумышленник имеет доступ как к хешированному паролю, так и к соли, поэтому при запуске атаки по словарю он может просто использовать известную соль при попытке взломать пароль.
Общедоступная соль делает две вещи: отнимает больше времени на взлом большого списка паролей и делает невозможным использование радужной таблицы.
Чтобы понять первый, представьте себе один файл паролей, который содержит сотни имен пользователей и паролей. Без соли я мог бы вычислить "md5(try [0])", а затем просканировать файл, чтобы увидеть, где-нибудь появляется этот хэш. Если соли присутствуют, тогда я должен вычислить "md5(salt[a] . Пытаюсь [0])", сравнить с записью A, затем "md5(salt[b] . Пытаюсь [0])", сравнить с записью B и т.д. Теперь у меня есть n
раза больше работы, где n
количество имен пользователей и паролей, содержащихся в файле.
Чтобы понять второй, вы должны понять, что такое радужный стол. Радужная таблица - это большой список предварительно вычисленных хэшей для часто используемых паролей. Представьте себе снова файл паролей без солей. Все, что мне нужно сделать, - это просмотреть каждую строку файла, вытащить хешированный пароль и найти его в радужной таблице. Мне никогда не нужно вычислять один хэш. Если поиск выполняется значительно быстрее, чем хеш-функция (что, вероятно, и есть), это значительно ускорит взлом файла.
Но если файл паролей солен, тогда радужная таблица должна содержать предварительно хешированный "salt. Пароль". Если соль достаточно случайная, это маловероятно. Вероятно, в моем списке часто используемых предварительно хешированных паролей (радужная таблица) будут такие вещи, как "привет", "foobar" и "qwerty", но я не собираюсь иметь такие вещи, как "jX95psDZhello" или "LPgB0sdgxfoobar" или "dZVUABJtqwerty" предварительно вычислены. Это сделало бы радужный стол слишком большим.
Таким образом, соль сводит злоумышленника обратно к одному вычислению на строку на попытку, которое, в сочетании с достаточно длинным, достаточно случайным паролем, является (вообще говоря) безотказным.
Другие ответы, кажется, не обращаются к вашему недопониманию темы, так что здесь идет:
Два разных использования соли
Я видел много уроков, предлагающих использовать соль следующим образом:
$hash = md5($salt.$password)
[...]
Другое использование я видел в моей системе Linux. В /etc/shadow хешированные пароли хранятся вместе с солью.
Вы всегда должны хранить соль с паролем, потому что для проверки того, что пользователь ввел в вашу базу паролей, вы должны объединить ввод с солью, хэшировать его и сравнить с сохраненным хешем.
Безопасность хеша
Теперь кто-то с радужным столом может поменять хеш и ввести "foobar".
[...]
поскольку известно, что обратный хеш te5SBM.7C25fFDu6bIRbX содержит "foo".
Невозможно обратить хеш как таковой (по крайней мере, в теории). Хеш "foo" и хэш "saltfoo" не имеют ничего общего. Изменение хотя бы одного бита на входе криптографической хеш-функции должно полностью изменить выход.
Это означает, что вы не можете создать радужную таблицу с общими паролями, а затем "обновить" ее солью. Вы должны принять во внимание соль с самого начала.
Это и есть причина того, почему вам нужен радужный стол. Поскольку вы не можете получить пароль из хэша, вы предварительно вычисляете все хэши наиболее вероятных используемых паролей, а затем сравниваете ваши хэши с их хэшами.
Качество соли
Но скажи
$salt=foo
"foo" будет крайне плохим выбором соли. Обычно вы используете случайное значение, закодированное в ASCII.
Кроме того, у каждого пароля есть своя собственная соль, отличающаяся (надеюсь) от всех других солей в системе. Это означает, что злоумышленник должен атаковать каждый пароль индивидуально, а не надеяться, что один из хэшей соответствует одному из значений в ее базе данных.
Атака
Если хакер каким-то образом смог достать этот файл, я не вижу, для чего служит соль,
Атака на радужный стол всегда нужна /etc/passwd
(или какая база данных паролей используется), или как бы вы сравнили хэши в радужной таблице с хешами реальных паролей?
Что касается цели: допустим, злоумышленник хочет создать радужную таблицу для 100000 часто используемых английских слов и типичных паролей (подумайте "секретно"). Без соли ей пришлось бы предварительно вычислить 100000 хешей. Даже с традиционной солью UNIX из 2 символов (каждый из 64 вариантов): [a–zA–Z0–9./]
) она должна была бы вычислить и сохранить 4 096 000000 хешей... довольно большое улучшение.
Идея с солью состоит в том, чтобы с помощью грубой силы угадать ее было намного сложнее, чем обычный символьный пароль. Радужные таблицы часто строятся с учетом специального набора символов и не всегда включают в себя все возможные комбинации (хотя они могут).
Таким образом, хорошим значением соли будет случайное 128-битное или более длинное целое число. Это то, что делает атаки на радужных столах неудачными. Используя разные значения соли для каждого сохраненного пароля, вы также гарантируете, что радужная таблица, построенная для одного конкретного значения соли (как в случае популярной системы с одним значением соли), не даст вам доступ ко всем пароли сразу.
Еще один замечательный вопрос со многими очень продуманными ответами - +1 к ТАК!
Одна небольшая вещь, о которой я не упомянул, это то, что, добавляя случайную соль к каждому паролю, вы фактически гарантируете, что два пользователя, которые случайно выбрали один и тот же пароль, будут создавать разные хэши.
Почему это важно?
Представьте себе базу паролей в крупной софтверной компании на северо-западе США. Предположим, он содержит 30000 записей, из которых 500 имеют пароль bluescreen. Предположим далее, что хакеру удается получить этот пароль, скажем, прочитав его по электронной почте от пользователя в ИТ-отдел. Если пароли несоленые, хакер может найти хеш-значение в базе данных, а затем просто сопоставить его с шаблоном, чтобы получить доступ к другим 499 учетным записям.
Соляные пароли гарантируют, что каждая из 500 учетных записей имеет уникальный (соль + пароль), генерируя разные хеш-коды для каждой из них и, таким образом, сокращая взлом одной учетной записи. И будем надеяться, что, по всей вероятности, любой пользователь, достаточно наивный, чтобы написать открытый текст в сообщении электронной почты, не имеет доступа к недокументированному API для следующей ОС.
Я искал хороший способ применения солей и нашел эту отличную статью с примером кода:
http://crackstation.net/hashing-security.htm
Автор рекомендует использовать случайные соли для каждого пользователя, так что получение доступа к соли не сделает весь список хэшей так легко взломать.
Чтобы сохранить пароль:
- Создайте длинную случайную соль, используя CSPRNG.
- Добавьте соль к паролю и зашифруйте его с помощью стандартной криптографической функции хеширования, такой как SHA256.
- Сохраните и соль, и хеш в записи базы данных пользователя.
Чтобы подтвердить пароль:
- Получить соль пользователя и хэш из базы данных.
- Добавьте соль к заданному паролю и хешируйте его, используя ту же хеш-функцию.
- Сравните хеш данного пароля с хешем из базы данных. Если они совпадают, пароль правильный. В противном случае пароль неверен.
Причина, по которой соль может привести к сбою атаки по радужному столу, состоит в том, что для n-битов соли радужный стол должен быть в 2^n раз больше размера таблицы без соли.
Ваш пример использования "foo" в качестве соли может увеличить радужный стол в 16 миллионов раз.
Учитывая пример Карла о 128-битной соли, это делает таблицу в 2^128 раз больше - теперь она велика - или, другими словами, сколько времени пройдет до того, как у кого-то появится такое большое портативное хранилище?
Большинство методов взлома шифрования, основанного на хэше, основаны на атаках методом перебора. Радужная атака - это, по сути, более эффективная атака по словарю, она разработана с использованием низкой стоимости цифрового хранилища, чтобы создать карту существенного подмножества возможных паролей для хэшей и облегчить обратное сопоставление. Этот тип атаки работает, потому что многие пароли имеют тенденцию быть либо достаточно короткими, либо использовать один из нескольких шаблонов форматов на основе слов.
Такие атаки неэффективны в случае, когда пароли содержат гораздо больше символов и не соответствуют распространенным форматам на основе слов. Пользователь с надежным паролем для начала не будет уязвим для этого стиля атаки. К сожалению, многие люди не выбирают хорошие пароли. Но есть компромисс: вы можете улучшить пароль пользователя, добавив к нему случайный мусор. Так что теперь вместо "hunter2" их пароль может стать "hunter2908! Fld2R75{R7/;508PEzoz^U430", который является гораздо более надежным паролем. Однако, поскольку теперь вам нужно хранить этот дополнительный компонент пароля, это снижает эффективность более надежного составного пароля. Как выясняется, такая схема все еще дает чистую выгоду, поскольку теперь каждый пароль, даже слабый, больше не уязвим для одной и той же предварительно вычисленной хэш-таблицы / радуги. Вместо этого каждая хэш-запись пароля уязвима только для уникальной хеш-таблицы.
Скажем, у вас есть сайт, который имеет слабые требования к надежности пароля. Если вы вообще не используете соль пароля, ваши хеш-коды уязвимы для предварительно вычисленных хеш-таблиц, таким образом, кто-то, имеющий доступ к вашим хешам, будет иметь доступ к паролям для большого процента ваших пользователей (однако многие используют уязвимые пароли, которые будут существенный процент). Если вы используете соль с постоянным паролем, то предварительно вычисленные хеш-таблицы больше не нужны, поэтому кому-то придется тратить время на вычисление настраиваемой хеш-таблицы для этой соли, хотя они могут делать это постепенно, хотя вычислительные таблицы охватывают все большие перестановки. проблемного пространства. Наиболее уязвимые пароли (например, простые пароли на основе слов, очень короткие буквенно-цифровые пароли) будут взломаны в течение нескольких часов или дней, менее уязвимые пароли будут взломаны через несколько недель или месяцев. Со временем злоумышленник получит доступ к паролям для постоянно растущего процента ваших пользователей. Если вы используете уникальную соль для каждого пароля, то для получения доступа к каждому из этих уязвимых паролей потребуются дни или месяцы.
Как вы можете видеть, когда вы переходите от соли без соли к соли с постоянной солью, вы увеличиваете на несколько порядков усилие по взлому уязвимых паролей на каждом шаге. Без соли самые слабые пароли ваших пользователей тривиально доступны, с постоянной солью эти слабые пароли доступны определенному злоумышленнику, а с уникальной солью стоимость доступа к паролям поднимается настолько высоко, что только самый решительный злоумышленник может получить доступ к крошечному подмножеству уязвимых паролей, и то только за большие деньги.
Это именно та ситуация, в которой вы находитесь. Вы никогда не сможете полностью защитить пользователей от неправильного выбора пароля, но вы можете повысить стоимость компрометации паролей ваших пользователей до уровня, который делает компрометацию пароля даже одного пользователя чрезмерно дорогой.
Одна из целей засолки - победить предварительно вычисленные хеш-таблицы. Если у кого-то есть список миллионов предварительно вычисленных хэшей, он не сможет найти $1$foo$te5SBM.7C25fFDu6bIRbX1 в своей таблице, даже если он знает хэш и соль. Им все равно придется переборщить.
Другая цель, как упоминает Карл С., - сделать грубое форсирование списка хэшей более дорогим. (дать им все разные соли)
Обе эти цели все еще достигнуты, даже если соли являются публичными.
Насколько я знаю, соль предназначена, чтобы сделать словарные атаки сложнее.
Это известный факт, что многие люди будут использовать общие слова для паролей вместо, казалось бы, случайных строк.
Таким образом, хакер может использовать это в своих интересах вместо того, чтобы использовать только грубую силу. Он не будет искать пароли, такие как aaa, aab, aac... но вместо этого будет использовать слова и общие пароли (например, имена хозяев колец!;))
Так что, если мой пароль - Леголас, хакер мог бы попробовать это и угадать его с "несколькими" попытками. Однако если мы солим пароль и он становится fooLegolas, хэш будет другим, поэтому атака по словарю будет неудачной.
Надеюсь, это поможет!
Я предполагаю, что вы используете функцию PHP --- md5() и переменные $ preced --- тогда вы можете попробовать эту статью Shadow Password HOWTO Специально для 11-го абзаца.
Кроме того, вы боитесь использовать алгоритмы дайджеста сообщений, вы можете попробовать настоящие алгоритмы шифрования, такие как те, что предоставляются модулем mcrypt, или более сильные алгоритмы дайджеста сообщений, такие как те, которые предоставляют модуль mhash (sha1, sha256 и другие).
Я думаю, что более сильный алгоритм дайджеста сообщений является обязательным. Известно, что у MD5 и SHA1 есть проблемы со столкновениями.