Как Devise защищает ваши пароли приложений Rails

1656519969 kak devise zashhishhaet vashi paroli prilozhenij rails

Тьяго Алвес

WsIjDqCJh9Mkz5YnCe8qO38OOfEevfkleLBm
Фото Джеймса Саттона на Unsplash

Devise – это невероятное решение для аутентификации для Rails с более чем 40 миллионами загрузок. Однако, поскольку он абстрагирует большинство криптографических операций, не всегда легко понять, что происходит за кулисами.

Одна из этих абстракций завершается устойчивостью. encrypted_password непосредственно в базе данных Поэтому мне всегда было интересно, что это действительно означает. Вот пример:

$2a$11$yMMbLgN9uY6J3LhorfU9iuLAUwKxyy8w42ubeL4MWy7Fh8B.CH/yO

Но что значит эта ложь?

Devise использует Bcrypt для безопасного хранения информации. На своем веб-сайте он упоминает, что используетАлгоритм хеширования паролей OpenBSD bcrypt(), позволяющий легко сохранять безопасный хеш паролей ваших пользователей”. Но что это за хэш? Как это работает и как обеспечивает безопасность хранимых паролей?

Вот что я хочу вам сегодня показать.

Давайте поработаем назад – от сохраненного хеша в вашей базе данных до процесса шифрования и дешифрования.

Этот хэш $2a$11$yMMbLgN9uY6J3LhorfU9iuLAUwKxyy8w42ubeL4MWy7Fh8B.CH/yO на самом деле состоит из нескольких компонентов:

  • Версия Bcrypt (2a) — версия алгоритма bcrypt(), используемого для создания этого хеша (хранится после первого $ знак)
  • Стоимость (11) – коэффициент стоимости, использованный для создания хэша (хранится после второго $ знак)
  • соль ($2a$11$yMMbLgN9uY6J3LhorfU9iu) — случайная строка, которая в сочетании с вашим паролем делает его уникальной (первые 29 символов)
  • контрольная сумма (LAUwKxyy8w42ubeL4MWy7Fh8B.CH/yO) – фактическая часть сохраненного хэша encrypted_password (строка, оставшаяся после 29 символов)
C1o8LTw8UCfepc7Tq3m5Yd1VGcMcT4XpRkBD

Давайте исследуем последние 3 параметра:

  • При использовании Devise, Cost значение устанавливается переменной класса, которая называется stretches, а значение по умолчанию – это 11. Он определяет количество раз хеширования пароля. (В вашем инициализаторе devise.rb вы можете настроить это на ниже значение для тестовой среды, чтобы сделать ваш набор тестов более быстрым.) *
  • The соль это случайная строка, используемая для сочетания с оригинальным паролем. Именно поэтому один и тот же пароль имеет разные значения при хранении в зашифрованном виде. (Смотрите ниже о том, почему это важно и что такое Rainbow Table Attackс.) **
  • The контрольная сумма – это фактически сгенерированный хэш пароля после сочетания со случайной солью.

Когда пользователь регистрируется в вашем приложении, он должен установить пароль. Прежде чем этот пароль будет сохранен в базе данных, случайная соль генерируется через BCrypt::Engine.generate_salt(cost) с учетом вышеупомянутого фактора стоимости. (Примечание: если pepper значение переменной класса установлено, оно прибавит свое значение к паролю, прежде чем его подсаливать.)

С этой солью (напр. $2a$11$yMMbLgN9uY6J3LhorfU9iu, который включает коэффициент стоимости), он вызовет BCrypt::Engine.hash_secret(password, salt), который вычисляет окончательный хэш, который будет сохранен с помощью сгенерированной соли и пароля, выбранного пользователем. Этот окончательный хэш (например, $2a$11$yMMbLgN9uY6J3LhorfU9iuLAUwKxyy8w42ubeL4MWy7Fh8B.CH/yO) в свою очередь будет храниться в encrypted_password столбец базы данных.

mKgk9fAildsnwkuXhmOU0SDIiflG-nI8FPUa

Но если этот хеш необратим и соль генерируется случайным образом на BCrypt::Password.create позвонить BCrypt::Engine.generate_salt(cost), как его можно использовать для пользовательского входа?

Вот где полезны разные хэш-компоненты. После нахождения записи, соответствующей электронной почте, предоставленной пользователем для входа, зашифрованный пароль извлекается и разбивается на различные компоненты, упомянутые выше (Версия Bcrypt, Стоимость, соль и контрольная сумма).

После этой начальной подготовки следующее:

  1. Убрать введите пароль (1234)
  2. Убрать соль сохраненного пароля ($2a$11$yMMbLgN9uY6J3LhorfU9iu)
  3. Сгенерировать хеш с пароля и соли, используя ту же версию bcrypt и коэффициент стоимости (BCrypt::Engine.hash_secret(“1234”, “$2a$11$yMMbLgN9uY6J3LhorfU9iu”))
  4. Убедитесь, что сохраненный хэш является таким же, как и вычисленное на шаге 3 ($2a$11$yMMbLgN9uY6J3LhorfU9iuLAUwKxyy8w42ubeL4MWy7Fh8B.CH/yO)
kJxy3TSK0VJ3fVqfFcVjmCCPCdgm1HyBb9C8

И именно так Devise надежно хранит пароли и защищает вас от ряда атак даже если ваша база данных сломана.

Свяжитесь с нами в Twitter @alvesjtiago и сообщите мне, была ли вам интересна эта статья! Спасибо, что читаете.

Lo-yU9BkzXFiqwgk5JS4RAKntUaE4KffvT5-

PS: Я отнюдь не эксперт по безопасности или криптографии, поэтому, пожалуйста, свяжитесь с нами, если вы обнаружите что-нибудь не так. Я надеюсь, что упростив некоторые понятия, будет легче понять, что происходит.

Спасибо @filipepina, @ivobenedito, @jackveiga, @joao_mags и @pedrosmmoreira за отзывы и предложения. Эта статья также доступна на сайте http://blog.tiagoalves.me/how-does-devise-keep-your-passwords-safe.

Больше информации о некоторых темах.

Фактор затрат*

Атаки Rainbow Table **

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

Ваш адрес email не будет опубликован.