我目前正在开发一个具有明文密码的项目。现在我们要求将所有明文密码更改为HASH。 数据库有密码字段和密码盐字段。
我在.Net中尝试了以下内容(我发现.Net 4使用HMACSHA256算法)使用数据库中已有的哈希密码。
// I retrieved the password and salt from database and hashed it
string authDetails = row["Password"] + row["PasswordSalt"].ToString(); //password salt - value from database
byte[] authBytes = System.Text.Encoding.UTF8.GetBytes(authDetails);
var hma = new System.Security.Cryptography.HMACSHA256();
byte[] hashedBytes = hma.ComputeHash(authBytes);
string hash = Convert.ToBase64String(hashedBytes);
并将上述哈希变量值存储在密码字段中。
我更改了配置设置passwordFormat =“hashed”。
如果我尝试使用密码登录,则登录失败。我无法使用旧密码登录。有什么想法吗?
谢谢!
编辑:只是为了澄清.. 我使用asp.net会员提供商。我在web.config中将PasswordFormat更改为'Hashed'。然后我调用Membership.ValidateUser来验证登录。 - 我认为它会自动哈希输入的密码并与数据库匹配。但我认为validateuser方法生成的哈希与上面生成的哈希不一样。
答案 0 :(得分:2)
HMAC是一个键控散列/哈希族。当您生成它的新实例时,.net将该键初始化为随机值。所以你得到了一个不同的家庭成员,从而产生了不同的结果。
原则上你可以切换到普通SHA256或使用salt作为密钥,即HMACSHA256(key=salt,message=password)
。但那是个坏主意。
你应该使用专门的密码散列函数,这很慢。有关密码哈希的详细信息,请参阅How to securely hash passwords? on security.SE。在.net中,Rfc2898DeriveBytes
实现了PBKDF2-HMAC-SHA1。
答案 1 :(得分:0)
你不需要使用hashmac,但只需像sha256那样哈希。 hashmack中的point是在使用key来验证消息时使用的,但是密码salting不需要它(hashmac需要额外的参数是密钥)
你需要的只是
sha256(password + salt)
答案 2 :(得分:0)
如果我尝试使用密码登录,则登录失败。我无法使用旧密码登录。有什么想法吗?
当您登录时,您相信所提供的用户名是正确的,并使用它来查找该用户的盐。然后使用用户输入的salt和密码来计算哈希值,方法与首次更新密码时的方式相同。现在,您可以将其与存储的密码进行比较。
所以你需要这样的代码:
string GetSalt(string username)
{
string sql = "SELECT PasswordSalt FROM [users] WHERE username= @username";
//connect to database and return that result
}
string ComputeHash(string username, string password)
{
string salt = GetSalt(username);
//should actually concatenate byte arrays, not strings
byte[] authBytes = System.Text.Encoding.UTF8.GetBytes(password + salt);
var hma = new System.Security.Cryptography.HMACSHA256();
byte[] hashedBytes = hma.ComputeHash(authBytes);
return Convert.ToBase64String(hashedBytes);
}
bool Login(string username, string password)
{
string hash = ComputeHash(username, password);
string sql = "SELECT COUNT(*) FROM [users] WHERE username= @username AND Password= @Hash";
// run that and make sure you get a row back
}