В статье Coda Hale «Как безопасно хранить пароль» утверждается, что:
В bcrypt встроены соли для предотвращения атак с радужного стола.
Он цитирует эту статью , в которой говорится, что в реализации OpenBSD bcrypt
:
OpenBSD генерирует 128-битную соль bcrypt из ключевого потока arcfour (arc4random (3)), заполненного случайными данными, которые ядро собирает по времени устройства.
Я не понимаю, как это может работать. В моей концепции соли:
- Он должен быть разным для каждого сохраненного пароля, поэтому для каждого из них необходимо создать отдельную радужную таблицу.
- Его нужно где-то хранить, чтобы его можно было повторить: когда пользователь пытается войти в систему, мы предпринимаем попытку ввода пароля, повторяем ту же процедуру с использованием соли и хэша, которую мы делали при первоначальном сохранении его пароля, и сравниваем
Когда я использую Devise (менеджер входа в Rails) с bcrypt, в базе данных нет столбца соли, поэтому я запутался. Если соль случайная и нигде не хранится, как мы можем надежно повторить процесс хеширования?
Короче говоря, как bcrypt может иметь встроенные соли ?
"OrpheanBeholderScryDoubt"
Я считаю, что эту фразу следовало бы сформулировать следующим образом:
Сама
bcrypt
утилита не поддерживает список солей. Скорее, соли генерируются случайным образом и добавляются к выходным данным функции, чтобы их потом запомнили (в соответствии с реализацией Javabcrypt
). Иными словами, «хеш», сгенерированныйbcrypt
не просто хешем. Скорее, это хеш и соль объединены.источник
Bcrypt
добавляет случайную соль "akd2! *", в результате чего получается "fooakd2! *", которая хэшируется и сохраняется. Позже я пытаюсь войти с паролем "бар". Чтобы убедиться, что я прав, нужно хешировать "barakd2! *". Если соль была сгенерирована случайным образом для начала, откуда она знает, как добавить ее обратно в «bar» перед хэшированием и сравнением?bcrypt
знает, как извлечь соль обратно из сгенерированного вывода (который хранится в базе данных). Когда приходит время для аутентификации,bcrypt
разделяет исходный вывод на его хеш и солт-компоненты. Солевой компонент применяется к входящему паролю, введенному пользователем.Чтобы сделать вещи еще яснее,
Регистрация / Направление входа ->
Пароль + соль шифруется ключом, сгенерированным из: стоимости, соли и пароля. мы называем это зашифрованное значение
cipher text
. затем мы добавляем соль к этому значению и кодируем ее с помощью base64. добавив стоимость к нему, и это полученная строка изbcrypt
:$2a$COST$BASE64
Это значение сохраняется в конце концов.
Что нужно сделать злоумышленнику, чтобы найти пароль? (другое направление <-)
В случае, если злоумышленник получит контроль над БД, он легко расшифрует значение base64 и сможет увидеть соль. соль не секрет. хотя это случайно. Тогда ему нужно будет расшифровать
cipher text
.Что еще более важно: в этом процессе нет хэширования, скорее дорогостоящее шифрование процессора - дешифрование. поэтому радужные таблицы здесь менее актуальны.
источник
Это из документации по интерфейсу PasswordEncoder от Spring Security,
Это означает, что нужно сопоставить rawPassword, который пользователь введет снова при следующем входе в систему, и сопоставить его с зашифрованным паролем Bcrypt, который хранится в базе данных во время предыдущего входа в систему / регистрации.
источник