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

В статье Coda Hale "Как безопасно хранить пароль" утверждается, что:

В bcrypt есть встроенные соли, чтобы предотвратить атаки радужного стола.

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

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

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

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

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

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

6 ответов

Решение

Это bcrypt:

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

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

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

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


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

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

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

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

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

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

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

bcrypt Сама утилита, похоже, не ведет список солей. Скорее, соли генерируются случайным образом и добавляются к выходным данным функции, чтобы их потом запомнили (в соответствии с реализацией Javabcrypt). Другими словами, "хэш", сгенерированный bcrypt это не просто хэш. Скорее, это хеш и соль сцепленные.

Это простые термины ...

Bcrypt не имеет базы данных, в которой хранится соль ...

Соль добавляется в хеш в формате base64 ....

Вопрос в том, как bcrypt проверяет пароль, когда у него нет базы данных ...?

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

Чтобы было понятнее,

Направление регистрации / входа ->

Пароль + соль зашифровывается с помощью ключа, созданного из: стоимости, соли и пароля. мы называем это зашифрованное значениеcipher text. затем мы добавляем соль к этому значению и кодируем его с помощью base64. прикрепив к нему стоимость, и это полученная строка изbcrypt:

$2a$COST$BASE64

Это значение со временем сохраняется.

Что нужно сделать злоумышленнику, чтобы найти пароль? (другое направление <-)

В случае, если злоумышленник получил контроль над БД, злоумышленник легко расшифрует значение base64, и тогда он сможет увидеть соль. соль не секрет. хотя это случайно. Затем ему нужно будет расшифроватьcipher text.

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

Представим себе таблицу с 1 хешированным паролем. Если хакер получит доступ, он будет знать соль, но ему придется рассчитывать большой список для всех общих паролей и сравнивать после каждого расчета. Это займет время, и он взломал бы только 1 пароль.

Представьте себе второй хешированный пароль в той же таблице. Соль видна, но тот же расчет, приведенный выше, должен повториться, чтобы взломать и эту, потому что соли разные.

Если бы не использовались случайные соли, было бы намного проще, почему? Если мы используем простое хеширование, мы можем просто сгенерировать хеши для общих паролей 1 раз (радужная таблица) и просто выполнить простой поиск по таблице или простой поиск файлов между хешами таблицы db и нашими предварительно рассчитанными хешами, чтобы найти простые пароли.

Это из документации по интерфейсу 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, который хранится в базе данных во время предыдущего входа в систему / регистрации.

Другие вопросы по тегам