Хеширование паролей: как обеспечить безопасность базы данных.

  • Главная
  • Хеширование паролей: как обеспечить безопасность базы данных.
Shape Image One
Хеширование паролей: как обеспечить безопасность базы данных.

Алгоритмы хеширования являются односторонними функциями. Они берут любую строку и превращают ее в «отпечаток пальца» фиксированной длины, который невозможно перевернуть. Это означает, что если ваши данные в вашей базе скомпрометированы, хакер не сможет получить пароли пользователя, если они были хорошо захешированы. 

Веб-сайты, использующие хеширование, обычно имеют такой рабочий процесс:

  1. Пользователь создает учетную запись.
  2. Их пароль хешируется и хранится в базе данных.
  3. Когда пользователь пытается войти в систему, хэш его введенного пароля сравнивается с хэшем, сохраненным в базе данных.
  4. Если хэши совпадают, пользователь может получить доступ к учетной записи.
  5. Если нет, то отправляется общее сообщение об ошибке, такое как «Введены неверные учетные данные», поэтому хакеры не могут отследить ошибку до имени пользователя или пароля.
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)
  • Создать новую случайную уникальную соль для КАЖДОГО хэша пароля
  • Генерировать ДЛИННЫЕ соли

Добавить комментарий