TL; использование DR Microsoft.AspNetCore.Cryptography.KeyDerivation , реализация PBKDF2 с SHA-512.
Хорошая идея начать с хэширования паролей - посмотреть, что говорят рекомендации OWASP . В список рекомендуемых алгоритмов входят Argon2, PBKDF2, scrypt и bcrypt. Все эти алгоритмы могут быть настроены для настройки времени, необходимого для хэширования пароля, и, соответственно, времени взлома его с помощью грубой силы. Все эти алгоритмы используют соль для защиты от атак радужных таблиц.
Ни один из этих алгоритмов не очень слабый, но есть некоторые отличия:
- bcrypt существует уже почти 20 лет, широко используется и
выдержал испытание временем Это довольно устойчиво к GPU
атаки, но не на ПЛИС
- Argon2 - новейшее дополнение, победившее в конкурсе хэширования паролей 2015 года. У него лучшая защита от атак на GPU и FPGA, но он мне не по вкусу
- Я мало что знаю о скрипте. Он был разработан, чтобы предотвратить атаки на GPU и FPGA, но я слышал, что он оказался не таким сильным, как первоначально утверждалось
- PBKDF2 - это семейство алгоритмов, параметризованных различными хэшами
функции. Он не обеспечивает особой защиты от атак на GPU или ASIC, особенно если используется более слабая хеш-функция, такая как SHA-1, но, тем не менее, он сертифицирован FIPS, если это важно для вас, и по-прежнему приемлем, если число итераций равно достаточно большой.
Исходя из одних алгоритмов, я бы, вероятно, выбрал bcrypt, PBKDF2 - наименее выгодный.
Однако это не полная история, потому что даже самый лучший алгоритм может быть ненадежным из-за плохой реализации. Давайте посмотрим, что доступно для платформы .NET:
- Bcrypt доступен через bcrypt.net . Говорят, что реализация основана на Java jBCrypt. В настоящее время на github есть 6 участников и 8 выпусков (все закрыты). В целом, это выглядит хорошо, однако я не знаю, проводил ли кто-нибудь аудит кода, и трудно сказать, будет ли обновленная версия доступна достаточно скоро, если будет обнаружена уязвимость. Я слышал, что переполнение стека отошло от использования bcrypt по таким причинам
- Вероятно, лучший способ использовать Argon2 - это привязка к
хорошо известная библиотека libsodium, например,
https://github.com/adamcaudill/libsodium-net. Идея в том, что
большая часть крипто реализуется через libsodium, который имеет значительные
поддержка, и «непроверенные» части довольно ограничены. Однако в
детали криптографии много значат, поэтому в сочетании с Argon2
сравнительно недавно я бы отнесся к этому как к экспериментальному варианту
- Долгое время в .NET была встроенная реализация PBKDF2 через
Rfc2898DeriveBytes класс. Тем не менее, реализация может использовать только хеш-функцию SHA-1, которая считается слишком быстрой, чтобы быть безопасной в настоящее время
- Наконец, самое последнее решение
Microsoft.AspNetCore.Cryptography.KeyDerivation пакет
доступно через NuGet. Он обеспечивает алгоритм PBKDF2 с хэш-функциями SHA-1, SHA-256 или SHA-512, что значительно лучше, чем
Rfc2898DeriveBytes
. Самым большим преимуществом здесь является то, что реализация предоставляется Microsoft, и хотя я не могу должным образом оценить криптографическое усердие разработчиков Microsoft по сравнению с BCrypt.net или libsodium, просто имеет смысл доверять этому, потому что, если вы используете приложение .NET, вы уже сильно полагаются на Microsoft. Мы также можем ожидать, что Microsoft выпустит обновления, если обнаружатся проблемы с безопасностью. Будем надеяться.
Чтобы подвести итоги исследования до этого момента, в то время как PBKDF2 может быть наименее предпочтительным алгоритмом из четырех, наличие поставляемой Microsoft реализации имеет преимущество, поэтому разумным решением будет использование Microsoft.AspNetCore.Cryptography.KeyDerivation
.
Последний пакет на данный момент предназначен для .NET Standard 2.0, поэтому доступен в .NET Core 2.0 или .NET Framework 4.6.1 или более поздней версии.Если вы используете более раннюю версию фреймворка, можно использовать предыдущую версию пакета 1.1.3 , которая предназначена для .NET Framework 4.5.1 или .NET Core 1.0.К сожалению, его невозможно использовать даже в более ранних версиях .NET.
Документация и рабочий пример доступны по адресу docs.microsoft.com .Однако не копируйте и не вставляйте его как есть, все еще есть решения, которые необходимо принять разработчику.
Первое решение - какую хеш-функцию использовать.Доступные опции включают SHA-1, SHA-256 и SHA-512.Из них SHA-1 определенно слишком быстр, чтобы быть безопасным, SHA-256 вполне приличный, но я бы порекомендовал SHA-512, потому что предположительно использование 64-битных операций затрудняет получение выгоды от атак на основе GPU.
Затем вам нужно выбрать длину вывода хэша пароля и длину соли.Не имеет смысла, чтобы вывод был длиннее, чем вывод хеш-функции (например, 512 бит для SHA-512), и, вероятно, было бы наиболее безопасно иметь его именно так.Что касается длины соли, мнения расходятся.128 бит должно быть достаточно, но в любом случае длина, превышающая длину вывода хеша, безусловно, не дает никаких преимуществ.
Далее, есть счетчик итераций.Чем оно больше, тем сложнее хэши паролей взломать, но чем дольше будет входить в систему пользователей. Я бы посоветовал выбрать его, чтобы хэширование занимало 0,25 - 1 секунду в типичной производственной системе, и в любом случае этодолжно быть не менее 10000.
Обычно, вы получите массив байтов в виде значений соли и хеша.Используйте Base64, чтобы преобразовать их в строки.Вы можете выбрать использование двух разных столбцов в базе данных или объединить соль и пароль в одном столбце, используя разделитель, которого нет в Base64.
Не забудьте разработать хранилище хэширования паролей таким образом, чтобыпозволяет беспрепятственно перейти к лучшему алгоритму хеширования в будущем.