System.Web.Helpers.Crypto - Где соль?
В прошлом при работе с паролями я всегда хранил соль и хешированный пароль отдельно в своем хранилище данных. Сегодня я искал обновление устаревшего кода для использования хеш-значения RFC 2898. Я наткнулся на методы Crypto.Hash
от System.Web.Helpers
. Похоже, что они сделают большую часть тяжелой работы для меня. Существуют методы GenerateSalt()
, HashPassword()
и VerifyHashedPassword()
. Методы HashPassword()
и VerifyHashedPassword()
не принимают значение соли. Документация MSDN для метода HashPassword()
гласит:
"Формат генерируемого хэш-потока - {0x00, соль, подраздел}, который кодируется base-64, прежде чем он будет возвращен."
Нужно ли беспокоиться о соли? В документации, по-видимому, говорится, что соль будет генерироваться автоматически и храниться в кодированном значении base-64? Это верно? Все, что мне нужно сохранить, это строка, возвращаемая из HashPassword()
?
Ответы
Ответ 1
Ответ
Все пароли должны быть солеными, чтобы безопасно их использовать. В этом случае, однако, вы правы. System.Web.Helpers.Crypto заботится о создании соли для вас. Вам не нужно его создавать. Он сохраняется в строке, возвращаемой Crypto.HashPassword().
Пример
Все, что вам нужно сделать, это что-то вроде этого.
using System.Web.Helpers;
public void SavePassword(string unhashedPassword)
{
string hashedPassword = Crypto.HashPassword(unhashedPassword);
//Save hashedPassword somewhere that you can retrieve it again.
//Don't save unhashedPassword! Just let it go.
}
public bool CheckPassword(string unhashedPassword)
{
string savedHashedPassword = //get hashedPassword from where you saved it
return Crypto.VerifyHashedPassword(savedHashedPassword, unhashedPassword)
}
Дополнительная информация
- Если вы хотите увидеть исходный код для класса Crypto, вы можете его просмотреть здесь.
- И здесь - хороший блог по классу и некоторые из его идей.
Ответ 2
Просто хотел поделиться этим сообщением:
http://forums.asp.net/t/1842429.aspx?System+Web+Helpers+Crypto+HashPassword
Здравствуйте,
Я смотрел новый метод Crypto HashPassword и VerifyMethod в System.Web.Helpers.
Оба метода используют соль, но они не возвращают Соль только Хешу.
Не нужна ли мне соль для ее хранения в базе данных? Я что-то не хватает?
Спасибо,
Miguel
..
Вы создадите соль, когда пользователь создаст учетную запись, а затем вы должны добавить его к паролю, прежде чем вызывать HashPassword. Вы хотите затем сохраните эту соль и хешированный пароль в вашей БД. Когда ты проверьте учетные данные, просто прочитайте соль из БД и добавьте ее в пароль от входа в систему перед вызовом VerifyHashedPassword. BrockAllen
..
Не уверен, понял ли я это... Потому что в HashPassword соль сгенерированный внутри метода:
Мигель
// Method in Crypto class
public static string HashPassword(string password)
{
if (password == null)
{
throw new ArgumentNullException("password");
}
// Produce a version 0 (see comment above) password hash.
byte[] salt;
byte[] subkey;
using (var deriveBytes = new Rfc2898DeriveBytes(password, SaltSize, PBKDF2IterCount))
{
salt = deriveBytes.Salt;
subkey = deriveBytes.GetBytes(PBKDF2SubkeyLength);
}
byte[] outputBytes = new byte[1 + SaltSize + PBKDF2SubkeyLength];
Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize);
Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, PBKDF2SubkeyLength);
return Convert.ToBase64String(outputBytes);
}
..
BrockAllen 11 сентября 2012 г. 19:50
Да, проигнорируйте это - это внутренняя соль для Rfc2898DeriveBytes и он получен из пароля, поэтому это не настоящая соль в контекст хранения паролей, поскольку он постоянно воссоздан для тот же пароль. Вы захотите по-прежнему делать свою соль на уровень строки пароля. Так что-то вроде этого:
public void CreateAccount(string username, string password)
{
var salt = Crypto.GenerateSalt();
var saltedPassword = password + salt;
var hashedPassword = Crypto.HashPassword(saltedPassword);
CreateAccount(username, salt, hashedPassword);
}
public void Verify(string username, string password)
{
var salt = GetSaltForUserFromDatabase(username);
var hashedPassword = GetHashedPasswordForUserFromDatabase(username);
var saltedPassword = password + salt;
if (Crypto.VerifyHashedPassword(hashedPassword, saltedPassword))
{
// valid password for this username
}
}
Это позволит вам хранить соль в базе данных вместе с хешированным засоленным паролем.
Дополнительная информация о хэшировании паролей с солью в целом из этого сообщения:
https://crackstation.net/hashing-security.htm
Чтобы сохранить пароль
- Генерировать длинную случайную соль с использованием CSPRNG.
- Подготовьте соль к паролю и установите его с помощью стандартной криптографической хэш-функции, такой как SHA256.
- Сохраните соль и хэш в записи базы данных пользователя.
Проверка пароля
- Извлеките пользовательскую соль и хэш из базы данных.
- Подготовьте соль к данному паролю и используйте его с помощью той же функции хэша.
- Сравните хэш заданного пароля с хешем из базы данных. Если они совпадают, пароль правильный. В противном случае пароль неверен.
Исходный код для класса Crypto:
http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Helpers/Crypto.cs