Asp.net хеширование паролей
Новый проект ASP.net Identity принес несколько полезных кодов и интерфейсов для безопасности сайта. Для реализации пользовательской системы с использованием интерфейсов (вместо использования стандартной реализации Entity Framework, включенной в шаблон MVC 5) IPasswordHasher
необходимо.
IPasswordHasher
интерфейс в ASP.net идентичности
namespace Microsoft.AspNet.Identity
{
public interface IPasswordHasher
{
string HashPassword(string password);
PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword);
}
}
Можно ли использовать соляризацию паролей для более безопасного шифрования в ASP.net Identity и через этот интерфейс?
3 ответа
"Можно ли использовать соляризацию паролей для более безопасного шифрования в ASP.net Identity и через этот интерфейс?"
Да, интерфейс предоставляется для новой реализации PasswordHasher, уже присутствующей в платформе Core.
Также обратите внимание, что реализация по умолчанию уже использует Salt+Bytes.
После создания кастома PasswordHasher
(сказать MyPasswordHasher
), вы можете назначить его экземпляру UserManager как userManager.PasswordHasher=new MyPasswordHasher()
Смотрите один пример такого IPasswordHasher
Для реализации пользовательской системы с использованием интерфейсов (вместо использования стандартной реализации Entity Framework, включенной в шаблон MVC 5) требуется IPasswordHasher.
Для реализации альтернативной системы от EF, Вы должны реализовать все Базовые интерфейсы. - Реализация IPasswordHasher не требуется. PasswordHasher уже предоставляется в Core Framework в качестве его реализации.
ВНИМАНИЕ ЗДОРОВЬЯ для ответа ниже: Знайте, какую версию ASP.Net Identity вы используете. Вы должны обращаться к исходному коду напрямую, если это одна из более новых версий из репозитория github.
На момент написания этой статьи текущая версия обработчика паролей ( 3.0.0-rc1 /.../ PasswordHasher.cs) значительно отличается от приведенного ниже ответа. Эта более новая версия поддерживает несколько версий алгоритма хеширования и задокументирована как (и может измениться к тому времени, когда вы прочитаете это):
Версия 2:
- PBKDF2 с HMAC-SHA1, 128-битная соль, 256-битный подключ, 1000 итераций.
- (См. Также: SDL Crypto Guide v5.1, часть III)
- Формат:
{ 0x00, salt, subkey }
Версия 3:
- PBKDF2 с HMAC-SHA256, 128-битная соль, 256-битный подключ, 10000 итераций.
- Формат:
{ 0x01, prf (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey }
- (Все UInt32 хранятся с прямым порядком байтов.)
Оригинальный ответ по-прежнему действителен для исходной версии ASP.Net Identity и выглядит следующим образом:
@ jd4u правильно, но пролить немного больше света, который не вписался бы в комментарий к его ответу:
Microsoft.AspNet.Identity.PasswordHasher : IPasswordHasher
уже соли для тебя,- что более важно, он использует
Rfc2898DeriveBytes
генерировать соль и хеш, - который использует промышленный стандарт PBKDF2 ( обсуждение SE здесь, рекомендация OWASP для PBKDF2 здесь).
- что более важно, он использует
- По умолчанию
Microsoft.AspNet.Identity.UserManager<TUser>
реализация используетMicrosoft.AspNet.Identity.PasswordHasher
как бетонIPasswordHasher
PasswordHasher
в свою очередь это действительно простая оболочка для (в конечном итоге)System.Security.Cryptography.Rfc2898DeriveBytes
Итак, если вы собираетесь использовать Rfc2898DeriveBytes
Просто используйте PasswordHasher
- все тяжелые работы уже сделаны (надеюсь, правильно) для вас.
подробности
Полный код, который в конечном итоге использует PasswordHasher, делает что-то очень похожее на:
int saltSize = 16;
int bytesRequired = 32;
byte[] array = new byte[1 + saltSize + bytesRequired];
int iterations = SOME; // 1000, afaik, which is the min recommended for Rfc2898DeriveBytes
using (var pbkdf2 = new Rfc2898DeriveBytes(password, saltSize, iterations))
{
byte[] salt = pbkdf2.Salt;
Buffer.BlockCopy(salt, 0, array, 1, saltSize);
byte[] bytes = pbkdf2.GetBytes(bytesRequired);
Buffer.BlockCopy(bytes, 0, array, saltSize+1, bytesRequired);
}
return Convert.ToBase64String(array);
Я столкнулся с проблемой при обновлении от членства до AspNet.Identity. Хеши Rfc2898 отличаются от тех, которые использовались ранее. Это не зря, но для изменения хешей всем пользователям потребуется сбросить свои пароли. В качестве решения эта пользовательская реализация делает его обратно совместимым:
public class MyPasswordHasher : PasswordHasher {
public FormsAuthPasswordFormat FormsAuthPasswordFormat { get; set; }
public MyPasswordHasher(FormsAuthPasswordFormat format) {
FormsAuthPasswordFormat = format;
}
public override string HashPassword(string password) {
return FormsAuthentication.HashPasswordForStoringInConfigFile(password, FormsAuthPasswordFormat.ToString());
}
public override PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword) {
var testHash = FormsAuthentication.HashPasswordForStoringInConfigFile(providedPassword, FormsAuthPasswordFormat.ToString());
return hashedPassword.Equals(testHash) ? PasswordVerificationResult.Success : PasswordVerificationResult.Failed;
}
}
Как только вы создадите свой экземпляр UserManager, просто установите хеш:
Usermanager.PasswordHasher = new MyPasswordHasher(FormsAuthPasswordFormat.SHA1);
Код жалуется, что HashPasswordForStoringInConfigFile
метод устарел, но это прекрасно, так как мы знаем, что все упражнение состоит в том, чтобы избавиться от старой технологии.