Вопрос или проблема
В настоящее время мы внедряем шифрование в конверте для нашего приложения. Это означает, что нам необходимо получить ключ из пароля пользователя, который затем будет использоваться в качестве ключа шифрования ключа (KEK) для обертывания другого ключа с использованием алгоритма AES-KW. В основном, в нашей базе данных обернутый ключ (который является ключом шифрования данных в нашем случае) будет храниться в той же схеме, что и хеши паролей пользователя в BCrypt.
Меня беспокоит: согласно RFC 3394, §2.2.3.1 всегда имеется постоянное начальное значение, предваряющее обернутый ключ для проверки целостности ключа. Однако в этом случае злоумышленник может просто попробовать перебрать алгоритм PBKDF2, итерируя пространство паролей, попробовать развернуть ключ с помощью производного KEK и проверить, совпадает ли начальное значение развернутого ключа с A6A6A6A6A6A6A6A6. В случае совпадения он не только сможет развернуть ключ, но и получить пароль пользователя, таким образом обходя BCrypt.
Пример:
Предположим, пользователь выбирает пароль из 5 символов [A-Za-z0-9]. Это означает, что кардинальность пространства паролей составляет (26 + 26 + 10)^5 = 62^5 ~ 9.16e8.
Наша текущая идея:
PBKDF2 с HMAC-SHA512 при 100.000 итерациях
BCrypt (предположим среднее время выполнения 0.1с на хеш)
Таким образом, для перебора PBKDF2 потребуется ~9.16e13 оценок хешей SHA512. Я искал на eBay и нашел стойки (в основном для добычи биткойнов) за $150 с хеш-скоростью 1TH/s (это означает 1e12 H/s). Это означает, что в среднем потребуется 9.16e1=91.6с для перебора пароля из 5 символов.
Используя пример с BCrypt, предположим 16 ядер + гипертрейдинг -> 320 BCrypt H/s на одном устройстве. Таким образом, потребуется 2862915.1с для перебора того же пароля на BCrypt, что составляет 33 дня.
Теперь основной вопрос:
почему OWASP все еще рекомендует PBKDF2, несмотря на легкую параллелизацию SHA хешей на GPU? Может быть, будет лучше получить ключ с sha256(bcrypt(password, salt))
вместо pbkdf2(password, salt)
? Или, возможно, даже pbkdf2(bcrypt(password, salt), salt)
?
Верно, что злоумышленник может выбрать более слабый из двух алгоритмов (который в данном случае является PBKDF2) и использовать его для атаки на пароль.
Хеширование одного и того же пароля дважды, как правило, не имеет большого смысла. Вы не только создаете укороченный путь, если не используете абсолютно одинаковые алгоритмы с абсолютно одинаковыми параметрами. Вы также подвергаете себя невыгодному положению: пока вам нужно выполнять хеш-вычисления дважды (один раз для хеша пароля, один раз для получения ключа), злоумышленнику нужно делать их лишь один раз. Это явно плохой подход, когда цель заключается в том, чтобы сделать вычисления как можно более сложными для атакующих, но все же приемлемыми для вашей системы.
Вам следует отказаться как от PBKDF2, так и от bcrypt. Это устаревшие алгоритмы, которые предлагают мало защиты от атак с использованием специализированного оборудования. Вместо этого переключитесь на современный алгоритм, такой как Argon2. Его можно использовать для одновременного получения ключа и проверочного хеша из пароля. Просто сделайте выход достаточно длинным. Например, если вам нужен 128-битный ключ AES и 128-битный хеш пароля, то генерируйте 256-битный вывод с Argon2. Используйте первую половину в качестве ключа AES и храните вторую половину в качестве хеша пароля.
Ответ или решение
Использование PBKDF2 в сочетании с AES-KW действительно ставит под сомнение эффективность BCrypt для хеширования паролей, и это требует более детального анализа. Давайте рассмотрим основные аспекты проблемы, предлагая взвешенный и обоснованный ответ.
1. Суть проблемы
Ваша система использует обёрточное шифрование (envelope encryption), что подразумевает, что при помощи пользовательского пароля извлекается ключ шифрования ключей (KEK), который затем используется для шифрования других ключей с помощью алгоритма AES-KW. Однако как указывает RFC 3394, если хранимый ключ имеет фиксированное начальное значение для проверки целостности, это открывает возможность для атаки на основе грубой силы.
2. Уязвимость PBKDF2
PBKDF2 основан на использовании SHA-512 и достаточно медленный при высоком числе итераций, что дает некоторые преимущества. Но как вы правильно подметили, атака на PBKDF2 может быть осуществлена путём итерации по пространству паролей, начиная с того, что злоумышленник сможет произвести дешифрование ключа и проверить начальное значение. Данная уязвимость в сочетании с доступностью специализированного оборудования для перебора паролей делает PBKDF2 подверженным атакам на долговременную защиту паролей.
3. Сравнение с BCrypt
BCrypt наделён защитой от параллельных вычислений и асимметричностью по отношению к вычислительным затратам. Он затрудняет атаку с использованием ускорителей, поскольку время вычисления для каждого хеша зависит от сложности алгоритма. В вашем случае, хотя PBKDF2 на первый взгляд кажется более жизнеспособным методом получения KEK, его уязвимость перед специализированными атаками следует рассматривать как критическую.
4. Выводы о выборе алгоритмов
OWASP рекомендует PBKDF2, но это решение может быть не идеальным в силу его подверженности атакам на современном оборудовании. Argon2 – это альтернатива, которая лучше справляется с требованиями к параллелизации и регулированию затрат по ресурсам. Оно может служить как для хеширования паролей, так и для извлечения ключей с необходимыми параметрами.
Использование комбинации PBKDF2 и AES-KW действительно может поставить под угрозу BCrypt, так как в случае успешного восстановления KEK злоумышленник получает не только доступ к шифрованному ключу, но и к паролю.
5. Рекомендации
Поскольку использование PBKDF2 в вашем случае ослабляет безопасность:
-
Рассмотрите переход на Argon2. Это обеспечит лучшую защиту на основании его внутренней архитектуры.
-
Избегайте двойного хеширования, так как это создаёт неравенство между вашим количеством вычислений и вычислениями злоумышленника.
-
Убедитесь, что AES-KW используется с modernas настройками безопасности, включая использование достаточного числа бит для ключа.
Итак, заключая, можно сказать, что использование PBKDF2 в сочетании с AES-KW действительно ослабляет защиту BCrypt, и настоятельно рекомендуется перейти к более современным и безопасным алгоритмам, таким как Argon2, для достижения более высокого уровня безопасности в вашей системе.