TL; DR используйте Microsoft. AspNetCore.Cryptography.KeyDerivation, реализующий PBKDF2 с SHA-512.
Хорошая идея для начала работы с хешированием паролей - это посмотреть, что говорится в рекомендациях OWASP. В список рекомендуемых алгоритмов входят Argon2, PBKDF2, scrypt и bcrypt. Все эти алгоритмы можно настроить так, чтобы регулировать время, необходимое для хеширования пароля, и, соответственно, время его взлома с помощью перебора. Все эти алгоритмы используют соль для защиты от атак радужных таблиц.
Ни один из этих алгоритмов не является ужасно слабым, но есть некоторые отличия:
- bcrypt существует уже почти 20 лет, широко используется и выдержал испытание временем. Он довольно устойчив к атакам на GPU, но не к FPGA.
- Argon2 - новейшее дополнение, победившее в конкурсе по хешированию паролей в 2015 году. У него лучшая защита от атак на GPU и FPGA, но, на мой взгляд, он появился слишком недавно.
- Я не очень разбираюсь в scrypt. Он был разработан для предотвращения атак с ускорением на GPU и FPGA, но я слышал, что он оказался не таким сильным, как первоначально утверждалось.
- PBKDF2 - это семейство алгоритмов, параметризованных различными хеш-функциями. Он не предлагает специальной защиты от атак на GPU или ASIC, особенно если используется более слабая хеш-функция, такая как SHA-1, но, тем не менее, он сертифицирован FIPS, если это важно для вас, и все еще приемлем, если количество итераций достаточно большой.
Основываясь только на алгоритмах, я бы, вероятно, выбрал bcrypt, PBKDF2 был наименее благоприятным.
Однако это еще не все, потому что даже лучший алгоритм может стать небезопасным из-за плохой реализации. Давайте посмотрим, что доступно для платформы .NET:
- Bcrypt доступен через bcrypt.net. Говорят, реализация основана на Java jBCrypt. В настоящее время на github 6 участников и 8 проблем (все закрыты). В целом, это выглядит хорошо, однако я не знаю, проводил ли кто-нибудь аудит кода, и трудно сказать, будет ли обновленная версия доступна достаточно скоро, если будет обнаружена уязвимость. Я слышал, что Stack Overflow отказался от использования 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-битных операциях затрудняет извлечение выгоды от атак на основе графического процессора.
Затем вам нужно выбрать длину вывода хэша пароля и длину соли. Нет смысла иметь вывод длиннее, чем вывод хэш-функции (например, 512 бит для SHA-512), и, вероятно, было бы наиболее безопасно иметь его именно так. По длине соли мнения расходятся. 128 бит должно быть достаточно, но в любом случае длина, превышающая длину выходного хэша, определенно не дает никаких преимуществ.
Далее идет счет итераций. Чем он больше, тем сложнее взломать хэши паролей, но тем больше времени требуется для входа пользователей в систему. Я бы посоветовал выбрать его так, чтобы хеширование занимало 0,25 - 1 секунду в типичной производственной системе, и в любом случае оно не должно быть меньше 10000.
Обычно вы получаете массив байтов в виде значений соли и хэша. Используйте Base64 для преобразования их в строки. Вы можете использовать два разных столбца в базе данных или объединить соль и пароль в один столбец, используя разделитель, которого нет в Base64.
Не забудьте разработать хранилище хеширования паролей таким образом, чтобы в будущем можно было плавно перейти к лучшему алгоритму хеширования.
person
ovolko
schedule
26.01.2018