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 для невежда, который требует, чтобы он был там.
Вы просто использовали сильную "соль".