NoneBcrypt в Go с KDF для определенной длины ключа вывода

Похоже, что экосистема Go просто имеет базовую реализацию bcrypt (golang.org/x/crypto/bcrypt), и разработчику оставлено в качестве упражнения извлекать ключ из закодированной выходной строки, а затем дополнительно расширять его для удовлетворения конкретного длина ключа, если вы собираетесь использовать его в качестве ключа шифрования, а не просто хранить его как пароль в БД где-нибудь. Меня смущает, что, кажется, нет быстрой обработки этой концепции онлайн для Go или просто в целом.

Рискуя внести ошибку, выполнив ее самостоятельно, я подозреваю, что меня заставят использовать scrypt, где, по крайней мере в Go, он принимает параметр output-length.

Я что-то пропустил? Есть ли где-нибудь в Go реализация bcrypt, которая принимает параметр длины ключа и напрямую управляет получением ключа приемлемой длины?

0 ответов

Bcrypt не является алгоритмом вывода ключей; это алгоритм хеширования паролей.

  • PBKDF2 может принимать пароль и выводить n желаемые биты
  • scrypt может принимать пароль и выводить n желаемые биты

Это ключевые производные функции. Они берут пароль и генерируютn биты, которые затем можно использовать в качестве ключа шифрования.

BCrypt не может этого сделать. BCrypt не является функцией получения ключей. Это функция хеширования паролей. Он всегда выводит одинаковое количество бит.

Бонус: bcrypt всегда выводит ровно 24 байта (192 бит), потому что вывод bcrypt является результатом шифрованияOrpheanBeholderScryDoubt.

Примечание: это не результат хеширования OrpheanBeholderScryDoubt- алгоритм bcrypt на самом деле шифрует OrpheanBeholderScryDoubt используя шифр blowfish (и повторяя шифрование 64 раза).

Сила bcrypt заключается в "дорогостоящей настройке ключа".

Бонус: сила bcrypt заключается в том, что он дорогой. А "дорогой" означает память. Чем больше памяти требует алгоритм, тем сильнее он противостоит атакам методом перебора.

  • SHA-2: может работать в 128 байтах ОЗУ
  • bcrypt: постоянно касается 4 КБ ОЗУ
  • scrypt: постоянно касается 16 Мб ОЗУ (в конфигурации по умолчанию в Android и LiteCoin)
  • Argon2: обычно рекомендуется настроить его для работы с 1 ГБ ОЗУ.

Защита от атак грубой силы означает защиту от распараллеливания. Алгоритм, требующий 128 байт, может выполнять 7 миллионов параллельных операций на видеокарте 1 ГБ.

Scrypt, для которого требуется 16 МБ ОЗУ, может работать только 62 параллельно.

Argon2, использующий 1 ГБ ОЗУ, может иметь только 1 работающий на видеокарте. И в любом случае он работает быстрее на процессоре.

Замените bcrypt на функцию деривации ключа (KDF)

Вы можете превратить bcrypt в функцию генерации ключей. Вы можете использовать стандартную функциюPBKDF2 сделать это за вас.

Обычно PBKDF2 называется:

String password = "hunter2";
String salt     = "sea salt 69 nice";

Byte[] key = PBKDF2(password, salt, 32, 10000); //32-bytes is 256 bits

Но вместо этого вы можете использовать результат строки bcrypt в качестве соли:

String password = "hunter2";
String salt     = bcrypt.HashPassword(password, 12);

Byte[] key = PBKDF2(password, salt, 32, 1); //32-bytes is 256-bits

И теперь вы сгенерировали 256-битный ключ "используя bcrypt". Это отличная хитрость.

На самом деле хак настолько изящен, что буквально то же самое, что и scrypt:

String password = "hunter2";
String salt     = ScryptExpensiveKeyHash(password, userSalt, ...);

Byte[] key = PBKDF2(password, salt, 32, 1); //32-bytes is 256-bits

Вывод

Bcrypt не является функцией вывода ключей. Это цель таких функций, как PBKDF2, scrypt (который использует PBKDF2) и argon2.

Использование bcrytp, когда вам разрешены только алгоритмы, одобренные NIST

Есть еще одна веская причина использовать эту конструкцию pbkdf2 с bcrypt.

Иногда "эксперт по безопасности", не понимающий, о чем идет речь, настаивает на использовании PBDKF2 для получения ключей. (Да, бывает). И вы будете пытаться повторять им снова и снова, что PBDKF2 - ужасно слабая система для получения ключей (SHA2, на котором он основан, выполняется слишком быстро, а 10000 или 100000 итераций далеко не достаточно, чтобы защитить вас от атак грубой силы - для этого были изобретены bcrypt, scrypt и argon2).

Но этот человек не позволит ему идти, и будет требовать использования PBKDF2. С этой конструкцией вы по-прежнему можете использовать bcrypt для безопасности и PBKDF2 для невежда, который требует, чтобы он был там.

Вы просто использовали сильную "соль".

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