Добавление пользовательского hashAlgorithmType в C# ASP.NET
У меня есть страница, на которой мне нужно повысить безопасность. Я использую встроенную функциональность MembershipProvider и в настоящее время hashAlgorithmType
установите SHA512. У меня есть библиотека BCrypt.NET (http://bcrypt.codeplex.com/), и она, кажется, работает хорошо, когда я вызываю ее функции из кода, но у меня самое плохое время, чтобы выяснить, как создать соответствующий <cryptographySettings>
раздел в Web.config, чтобы позволить мне создать hashAlgorithmType
,
Я нашел следующий фрагмент кода в Интернете:
<mscorlib>
<cryptographySettings>
<cryptoNameMapping>
<cryptoClasses>
<cryptoClass MyHash="MyHashClass, MyAssembly
Culture=neutral, PublicKeyToken=a5d015c7d5a0b012,
Version=1.0.0.0"/>
<cryptoClass MyCrypto="MyCryptoClass, MyAssembly
Culture=neutral, PublicKeyToken=a5d015c7d5a0b012,
Version=1.0.0.0"/>
</cryptoClasses>
<nameEntry name="System.Security.Cryptography.HashAlgorithm"
class="MyHash"/>
</cryptoNameMapping>
<oidMap>
<oidEntry OID="1.3.36.3.2.1" name="MyCryptoClass"/>
</oidMap>
</cryptographySettings>
</mscorlib>
Назовите меня нубом, если хотите, но у меня, очевидно, нет необходимых знаний, чтобы понять это. Все, что мне нужно, это метод, чтобы сказать поставщику членства, что-то вроде <hashAlgorithmType="bcrypt">
соответствует чему-то вроде string hashed = BCrypt.HashPassword(password, BCrypt.GenerateSalt(12));
зашифровать и bool matches = BCrypt.CheckPassword(candidate, hashed);
расшифровать. Пожалуйста, скажите мне, что есть простой ответ. Я могу переписать систему входа в систему с нуля, если потребуется, но у меня уже есть работающая реализация, которую я действительно хотел бы просто изменить алгоритм хеширования.
3 ответа
Я считаю, что шаблон конфигурации должен быть применен к файлу machine.config; это не обязательно хороший шаг, если вам нужно легко развернуть этот код.
Вы можете программно зарегистрировать примитивы шифрования BCrypt в классе CryptoConfig с помощью вызова AddAlgorithm с именем, которое вы можете использовать позже.
До тех пор пока поставщик хеша BCrypt реализует HashAlgorithn
Вы должны быть в состоянии зарегистрировать это просто, вы также можете проверить это, позвонив HashAlgorithm.Create(string)
с именем, которое вы используете для проверки правильности построения алгоритма.
После этого провайдер членства сможет использовать его без проблем. Вот хорошая статья на эту тему.
Обновить
(глубокий вдох) - извинения, если это д-р.
Итак, прочитав о хешировании паролей BCrypt.Net - это, очевидно, хорошо, и следует принятой практике. Это также совершенно несовместимо с тем, как HashAlgorithm
класс работает, потому что он требует дополнительного состояния, чтобы работать магически, и его нельзя просто расширить для реализации HashAlgorithm
контракт.
Таким образом, у вас есть выбор - придерживаться MembershipProvider
и использовать SHA512, как вы уже используете - вы говорите о повышении безопасности на странице, поэтому я думаю, что могут быть проблемы с самой аутентификацией, а не с хранением паролей (что, конечно, должно все же быть сделано правильно) - поэтому попробуйте просто убедиться, что трафик аутентификации отправляется по HTTPS, если это еще не сделано.
Использование алгоритмов растяжения паролей вслепую имеет свои проблемы - см. Ответы на мою недавнюю SO по этой теме - если вы делаете растягивание на сервере, вы можете в конечном итоге вызвать DOS-атаку на сайт!
Другой вариант, как вы предложили, полностью управлять членством - таким образом, вы можете использовать любой тип данных и вручную управлять необходимым хранением информации о пароле.
Мои сайты теперь используют алгоритм, очень похожий на PBKDF2, который я взял из книги Брюса Шнайера и Нильса Фергюсона "Практическая криптография", для которой я использую 512-битную случайную соль и SHA512 (хранилище дешево), а также многие тысячи итераций для хеширования открытого текста. Сервер тестирует себя один раз для каждого домена приложения, чтобы установить "уровни" защиты, равные диапазонам в миллисекунды - таким образом, со временем вновь хешированные пароли будут получать постоянный уровень защиты, даже если улучшится оборудование. Библиотека также является автономной, и я смог развернуть ее на SQL Server 2008 R2, чтобы предоставить CLR SP, если нам нужно будет создавать записи паролей на уровне SQL.
Но это только защищает пароли - тогда вам нужен механизм аутентификации, который может защитить сам процесс входа в систему; плюс еще одна система для защиты аутентифицированного маркера сеанса (система cookie аутентификации.Net на самом деле очень хороша для этого).
Исходя из этого, я потратил неделю на реализацию примитивов SCRAM, которые затем подключил к своим веб-сервисам MVC для аутентификации, и я планирую сделать то же самое, чтобы разрешить вход в систему через веб-браузер с использованием Javascript (блокировка не-JS-клиентов). Ключ в том, что клиент делает все вычисления хеша; таким образом, я придерживался SHA, потому что зрелые реализации легко доступны практически в любой среде (например, у нас есть приложения для iPhone - и они также должны проходить аутентификацию).
Однако в вашем случае, учитывая существующие инвестиции в MembershipProvider, я бы посчитал достаточным 512 бит SHA плюс SSL плюс cookie-файл проверки подлинности Asp.Net, если база данных действительно безопасна (!) И у вас нет SQL-инъекции. дыры в сайте.
Для реализации BCrypt HashAlgorithm, см. Мой ответ на подобный вопрос здесь.
Вам нужно будет создать подписанную сборку с примером кода в моем ответе, а затем изменить необходимые настройки:
<cryptoNameMapping>
<cryptoClasses>
<cryptoClass MyHash="BCryptHasher, MySignedAssemblyName
Culture=neutral, PublicKeyToken=<my public key for singed assembly>,
Version=1.0.0.0"/>
</cryptoClasses>
<nameEntry name="System.Security.Cryptography.HashAlgorithm" class="MyHash"/>
</cryptoNameMapping>
Чтобы иметь возможность зарегистрировать пользовательский hashAlgorythmType, первое, что вам нужно, это тип, который фактически реализует HashAlgorythm. Если BCrypt реализует его, это ваш счастливый день, но, очевидно, он НЕ реализует его, так что это ваша проблема.
Там действительно нет работы для этого, как реализация HashAlgorithm
это требование для возможности зарегистрировать это так.
Так что вам нужно либо написать обертку вокруг BCrypt для реализации HashAlgorithm
или, что невозможно, измените сам BCrypt для его реализации.
Если вам не очень-очень повезло и BCrypt написан так, что легко поддается такой модификации, это может потребовать некоторых нетривиальных усилий.