Как bcrypt может иметь встроенные соли? - PullRequest
541 голосов
/ 26 июля 2011

Статья Коды Хейл "Как безопасно хранить пароль" утверждает, что:

bcrypt имеет встроенные соли для предотвращения атак радужного стола.

Он цитирует эту статью , в которой говорится, что в реализации OpenBSD bcrypt:

OpenBSD генерирует 128-битную соль bcrypt из arcfour (arc4random (3)) ключевой поток, заполненный случайными данными, которые ядро ​​собирает по времени устройства.

Я не понимаю, как это может работать.В моем понимании соли:

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

КогдаЯ использую Devise (менеджер входа в Rails) с bcrypt, в базе данных нет столбца соли, поэтому я в замешательстве.Если соль случайная и нигде не хранится, как мы можем надежно повторить процесс хеширования?

Короче говоря, как может bcrypt иметь встроенные соли ?

Ответы [ 3 ]

703 голосов
/ 26 июля 2011

Это bcrypt:

Генерация случайной соли.Коэффициент стоимости был предварительно настроен.Соберите пароль.

Извлеките ключ шифрования из пароля, используя соль и коэффициент стоимости.Используйте его для шифрования известной строки. Магазин стоимость, соль, и зашифрованный текст.Поскольку эти три элемента имеют известную длину, их легко объединить и сохранить в одном поле, но потом можно будет разбить их на части.

Когда кто-то пытается аутентифицироваться, извлекает сохраненную стоимость и соль.Получите ключ от ввода пароля, стоимости и соли.Зашифруйте ту же самую известную строку.Если сгенерированный зашифрованный текст совпадает с сохраненным зашифрованным текстом, пароль совпадает.

Bcrypt работает очень похоже на более традиционные схемы, основанные на алгоритмах, подобных PBKDF2.Основным отличием является использование производного ключа для шифрования известного простого текста;другие схемы (разумно) предполагают, что функция получения ключа является необратимой, и сохраняют полученный ключ напрямую.


Сохраненный в базе данных, bcrypt "хеш" может выглядеть примерно так:

$ 2a $ 10 $ vI8aWBnW3fID.ZQ4 / zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa

На самом деле это три поля, разделенные символом "$":

  • 10 - коэффициент стоимости;Используются 2 10 итерации функции вывода ключа (кстати, этого недостаточно. Я бы рекомендовал стоимость 12 или более).
  • vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa - сольи зашифрованный текст, объединенный и закодированный в модифицированной Base-64.Первые 22 символа декодируются до 16-байтового значения для соли.Остальные символы - это зашифрованный текст, который нужно сравнить для проверки подлинности.

Этот пример взят из документации для реализации Ruby в Coda Hale.

164 голосов
/ 26 июля 2011

Я считаю, что эту фразу следовало бы сформулировать следующим образом:

bcrypt содержит соли , встроенные в сгенерированные хэши , чтобы предотвратить атаки радужных таблиц.1008 *

Сама утилита bcrypt не поддерживает список солей.Скорее, соли генерируются случайным образом и добавляются к выходным данным функции, чтобы впоследствии их запомнили (согласно реализации Java bcrypt).Иными словами, «хэш», сгенерированный bcrypt, не является , а хешем.Скорее, это хеш и объединенной соли.

0 голосов
/ 21 апреля 2019

Это из документации по интерфейсу PasswordEncoder от Spring Security,

 * @param rawPassword the raw password to encode and match
 * @param encodedPassword the encoded password from storage to compare with
 * @return true if the raw password, after encoding, matches the encoded password from
 * storage
 */
boolean matches(CharSequence rawPassword, String encodedPassword);

Это означает, что нужно будет сопоставить rawPassword, который пользователь введет снова при следующем входе в систему, и сопоставить его с закодированным паролем Bcrypt, который сохраняется в базе данныхво время предыдущего входа / регистрации.

...