System.Web.Helpers.Crypto-其中';这是盐
本文关键字:Web Helpers Crypto- 其中 System | 更新日期: 2023-09-27 18:23:35
在过去处理密码时,我总是在数据存储中分别存储salt和散列密码。今天,我想更新一些遗留代码以使用RFC2898哈希值。我偶然发现了System.Web.Helpers
的Crypto.Hash
方法。看起来这些方法将为我完成大部分繁重的工作。有GenerateSalt()
、HashPassword()
和VerifyHashedPassword()
方法。HashPassword()
和VerifyHashedPassword()
方法不采用salt值。针对HashPassword()
方法的MSDN文档中写道:
生成的哈希字节流的格式为{0x00,salt,subkey},在返回之前已进行了base-64编码。
我需要担心盐吗?文档似乎说salt将自动生成并存储在base-64编码值中?这是正确的吗?我只需要存储从HashPassword()
返回的字符串?
答案
所有密码都需要加盐才能安全地进行哈希。然而,在这种情况下,你是正确的;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
类的信息,可以在这里查看 - 这里有一个关于这门课的好博客,以及它背后的一些想法
我只想分享这篇文章:
http://forums.asp.net/t/1842429.aspx?System+Web+助手+加密+哈希密码
你好,
我一直在研究System.Web.Helpers中新的Crypto-HashPassword和VerifyMethod方法。
这两个方法都使用Salt,但它们不返回Salt,只返回Hash
我不需要盐来将其存储在数据库中吗?我是不是错过了什么
谢谢,
Miguel
当用户创建帐户时,您会生成salt,然后在调用HashPassword之前,您需要将其附加到密码中。you had 的常用口语形式然后将salt和散列后的密码存储在数据库中。当你验证凭据只需从数据库中读取salt并将其附加到调用VerifyHashedPassword之前登录的密码。BrockAllen
不确定我是否理解。。。因为在HashPassword中,Salt是方法内部生成:
Miguel
// 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);
}
布罗克艾伦2012年9月11日下午07:50
是的,忽略它——它是Rfc2898DeriveBytes的内部salt它是从密码派生的,所以它不是存储密码的上下文,因为它始终是为相同的密码。你仍然想在密码字符串级别。这样的东西:
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
}
}
这将允许您将您的salt与散列后的salt密码一起存储在数据库中。
关于使用salt进行密码哈希的其他信息,请参阅本文:https://crackstation.net/hashing-security.htm
存储密码
- 使用CSPRNG生成长随机盐
- 将salt预先添加到密码中,并使用标准加密哈希函数(如SHA256)对其进行哈希
- 将salt和hash都保存在用户的数据库记录中
验证密码
- 从数据库中检索用户的salt和hash
- 将salt预先设置为给定的密码,并使用相同的哈希函数对其进行哈希
- 将给定密码的哈希与数据库中的哈希进行比较。如果它们匹配,则密码是正确的。否则,密码不正确
加密类的源代码:
http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Helpers/Crypto.cs