Какой тип столбца / длину следует использовать для хранения хешированного пароля Bcrypt в базе данных? - PullRequest
278 голосов
/ 04 мая 2011

Я хочу сохранить хешированный пароль (используя BCrypt) в базе данных.Что будет хорошим типом для этого, и какой будет правильная длина?Хэши паролей с BCrypt всегда имеют одинаковую длину?

РЕДАКТИРОВАТЬ

Пример хэша:

$2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu

После некоторого хэшированияпароли, кажется, что BCrypt всегда генерирует хэши по 60 символов.

EDIT 2

Извините, что не упомянул реализацию.Я использую jBCrypt .

Ответы [ 4 ]

335 голосов
/ 04 мая 2011

Модульный формат шифрования для bcrypt состоит из

  • $2$, $2a$ или $2y$, идентифицирующего алгоритм хеширования , и формата
  • aдвухзначное значение, обозначающее параметр стоимости, за которым следует $
  • значение в кодировке base-64 длиной 53 символа (используется алфавит ., /, 0 - 9,A - Z, a - z, который отличается от стандартного кодирования Base 64 алфавит), состоящего из:
    • 22 символов соли (фактически только 128 битов)из 132 декодированных битов)
    • 31 символов зашифрованного вывода (фактически только 184 бит из 186 декодированных битов)

Таким образом, общая длина составляет 59 или60 байтов соответственно.

Поскольку вы используете формат 2a, вам потребуется 60 байтов.И поэтому для MySQL я рекомендую использовать CHAR(60) BINARY или BINARY(60) (см. _bin и бинарные параметры сортировки дляинформация о разнице).

CHAR не является бинарно-безопасной, и равенство зависит не только от значения байта, но и от фактического сопоставления;в худшем случае A считается равным a.Подробнее см. _bin и binary .

48 голосов
/ 17 мая 2013

Хеш Bcrypt может храниться в столбце BINARY(40).

BINARY(60), как показывают другие ответы, - самый простой и естественный выбор, но если вы хотите максимизировать эффективность хранения, выможет сохранить 20 байтов, без потерь деконструируя хеш.Я подробно описал это на GitHub: https://github.com/ademarre/binary-mcf

Хеши Bcrypt следуют структуре, называемой модульным форматом шифрования (MCF). Binary MCF (BMCF) декодирует эти текстовые хэш-представления в более компактную двоичную структуру.В случае Bcrypt результирующий двоичный хэш составляет 40 байтов.

Гамбо проделал хорошую работу по объяснению четырех компонентов хэша Bcrypt MCF:

$<id>$<cost>$<salt><digest>

Декодирование в BMCF выглядит следующим образомэто:

  1. $<id>$ может быть представлено в 3 битах.
  2. <cost>$, 04-31, может быть представлено в 5 битах.Соедините их вместе для 1 байта.
  3. 22-символьная соль - это (нестандартное) представление base-64 из 128 битов.Декодирование Base-64 дает 16 байтов.
  4. Дайджест хэша из 31 символа может быть декодирован Base-64 до 23 байтов.
  5. Соберите все вместе для 40 байтов: 1 + 16 + 23

Вы можете прочитать больше по ссылке выше или изучить мою реализацию PHP , также на GitHub.

21 голосов
/ 21 июля 2015

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

Со страницы справочника:

Обратите внимание, что эта константа может изменяться со временем по мере добавления в PHP новых и более сильных алгоритмов.По этой причине длина результата от использования этого идентификатора может меняться со временем.Поэтому рекомендуется сохранить результат в столбце базы данных, который может быть расширен за пределы 60 символов (было бы неплохо выбрать 255 символов).

Использование bcrypt, даже если вы1 миллиард пользователей (то есть, вы в настоящее время конкурируете с Facebook) для хранения 255-байтовых хэшей паролей, это будет всего ~ 255 ГБ данных - размером с небольшой жесткий диск SSD.Крайне маловероятно, что хранение хэша пароля станет узким местом в вашем приложении.Однако в случае, если пространство хранения действительно является по какой-то причине проблемой , вы можете использовать PASSWORD_BCRYPT, чтобы заставить password_hash() использовать bcrypt, даже если это не значение по умолчанию.Просто будьте в курсе всех уязвимостей, обнаруженных в bcrypt, и просматривайте примечания к выпуску каждый раз, когда выходит новая версия PHP.Если алгоритм по умолчанию когда-либо изменяется, было бы хорошо рассмотреть почему и принять обоснованное решение, использовать новый алгоритм или нет.

18 голосов
/ 04 мая 2011

Я не думаю, что есть какие-то хитрые уловки, которые вы можете сделать, храня это, как вы можете сделать, например, с хешем MD5.

Я думаю, что вам лучше всего хранить его как CHAR(60)как всегда 60 символов

...