Алгоритмы хеширования являются односторонними функциями. Они берут любую строку и превращают ее в «отпечаток пальца» фиксированной длины, который невозможно перевернуть. Это означает, что если ваши данные в вашей базе скомпрометированы, хакер не сможет получить пароли пользователя, если они были хорошо захешированы.
Веб-сайты, использующие хеширование, обычно имеют такой рабочий процесс:
- Пользователь создает учетную запись.
- Их пароль хешируется и хранится в базе данных.
- Когда пользователь пытается войти в систему, хэш его введенного пароля сравнивается с хэшем, сохраненным в базе данных.
- Если хэши совпадают, пользователь может получить доступ к учетной записи.
- Если нет, то отправляется общее сообщение об ошибке, такое как «Введены неверные учетные данные», поэтому хакеры не могут отследить ошибку до имени пользователя или пароля.
hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
hash("hellu") = 3937f988aeb57b6fd75b9c71bf17b9658ec97823bab613df438389b0c896b724
hash("danny") = 668e2b73ac556a2f051304702da290160b29bad3392ddcc72074fefbee80c55a
ПРИМЕЧАНИЕ. Для хеширования пароля могут использоваться только безопасные или криптографические хеш-функции (SHA256, SHA512, RipeMD, WHIRLPOOL и т.д.).
К сожалению, просто криптографическое хеширование паролей не обеспечивает безопасность.
Взломать хеш
Самый простой способ расшифровать хеш - просто угадать пароль, хешировать предположение и сравнить его с хешем фактического пароля, который вы пытаетесь разгадать.
Подбор проходит через все возможные комбинации символов. Несмотря на то, что в конечном итоге можно на 100% взломают любой заданный пароль, этот метод трудно использовать из-за его высокой вычислительной стоимости. Некоторые пароли, даже довольно короткие по длине, могут взломать (буквально) тысячи лет, используя грубую силу.
Trying aaa : failed
Trying aab : failed
Trying aac : failed
...
Trying acb : failed
Trying acc : success!
При атаках по словарю используется файл, содержащий часто используемые слова, фразы или пароли, которые, вероятно, являются используемым паролем. Есть даже базы данных с 100000 (или где-то близко) наиболее часто используемых паролей. Атака хэширует эти пароли и сравнивает хеш с паролем для взлома. Этот метод, конечно, быстрее, чем с помощью атаки грубой силы.
Таблицы поиска могут улучшить производительность взлома, предварительно вычисляя хэши, поэтому, когда приходит время угадать пароль, программе не нужно тратить время на вычисление, фактически хешируя догадки.
В следующем разделе мы рассмотрим «засолку», которая делает невозможным 100% использование этих методов взлома.
Соление
Причина, по которой таблицы поиска, атаки по словарю и атаки методом "грубой силы" могут работать, заключается в том, что пароли каждый раз хэшируются одинаково. Мы можем рандомизировать хеш, добавляя случайную строку, называемую солью, к паролям ДО хеширования.
hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
hash("hello" + "jHjdbJShdiodb") = 6f7f167a978166ee23b32c9531ce5dc23ae8fc26e412045858d938d11470831f
Если у пользователя пароль qwerty, мы получим следующий хеш: d8578edf8458ce06fbc5bb76a58c5ca4. Если злоумышленник получит доступ к нашей базе, для подбора паролей он может воспользоваться уже готовыми сервисами, в которых уже есть значения, дающие данный хеш, либо сбрутить самому.
Для защиты от уже готовых таблиц хешей с значениями, можно использовать статическую соль:
$password = md5($password . "MyUniqueSault");
Сейчас при том же пароле qwerty мы получим совершенно другой хеш bdadb0330124cda0e8499c9cd118f7bd. Готовые таблицы уже не помогут злоумышленнику, ему придется использовать брутфорс. Вот здесь и кроется минус статической соли: злоумышленник сможет сгенерировать свою таблицу хешей со статической солью и получить значения большинства паролей из базы. Для устранения этого минуса используется уникальная соль к каждому хешу:
$sault = GenerateRandomString();
$password = md5($password . $sault);
Т.е. теперь помимо логина/хеша пароля в базе необходимо будет хранить значение сгенерированной соли для каждого пользователя. Разберем пример: у нас два пользователя: user1 и user2. Оба используют пароль qwerty. Но у первого была сгенерирована соль zxcv а у второго asdf. В итоге у пользователей при одинаковом пароле будут различные хеши: 1d8f3272b013387bbebcbedb4758586d и a192862aa3bf46dffb57b12bdcc4c199.Что это дает: теперь нельзя будет сгененерировать одну таблицу хешей, для нахождения значения хеша с динамической солью придется генерировать заново.
Что нужно и чего не нужно солить
Не рекомендуется:
- Повторно использовать одну и ту же соль для каждого хэша пароля
- Использовать короткие соли
- Использовать странные двойные хэши (например: hash(hash(hash(‘mypass’)))) в соли
Рекомендуется:
- Генерация случайных солей с использованием криптографически безопасного генератора псевдослучайных чисел (CSPRNG)
- Создать новую случайную уникальную соль для КАЖДОГО хэша пароля
- Генерировать ДЛИННЫЕ соли
0 комментариев
Добавить комментарий