【发布时间】:2016-07-15 13:57:00
【问题描述】:
使用 sha256 和 salt 处理散列密码,我的验证方法总是返回 false。在调试时,我注意到返回时它将前 32 位数组与 64 位数组进行比较。我不知道我在哪里出错了。
public static byte[] Hash(string value, byte[] salt)
{
salt = new byte[64];
using (var rng = new RNGCryptoServiceProvider())
{
rng.GetBytes(salt);
}
return Hash(Encoding.UTF8.GetBytes(value), salt);
}
public static byte[] Hash(byte[] value, byte[] salt)
{
var saltedValue = value.Concat(salt).ToArray();
return new SHA256Managed().ComputeHash(saltedValue);
}
public bool ConfirmPassword(string password)
{
var passwordSalt = new byte[64];
using (var context = new DbConnection())
{
context.Connection.Open();
context.SqlCommand.Connection = context.Connection;
context.SqlCommand.CommandText = "select salt from users where name='test'";
var reader = context.SqlCommand.ExecuteReader();
while (reader.Read())
{
passwordSalt = reader["salt"] as byte[];
}
}
var passwordHash = Hash(password, passwordSalt);
return passwordHash.SequenceEqual(passwordSalt);
}
更新 所以如果我做对了:
public bool ConfirmPassword(string password)
{
var userSalt = new byte[64];
var temp = new byte[64];
using (var context = new DbConnection())
{
context.Connection.Open();
context.SqlCommand.Connection = context.Connection;
context.SqlCommand.CommandText = "select password from users where name='test'";
var reader = context.SqlCommand.ExecuteReader();
while (reader.Read())
{
temp = reader["password"] as byte[];
}
}
var passwordHash = Hash(password, userSalt);
return passwordHash.SequenceEqual(temp);
}
但它也让我返回错误
【问题讨论】:
-
您将盐与散列密码进行比较。这显然总是不同的。
-
@MarkoJuvančič,我需要将数据库中的哈希密码与输入的哈希密码进行比较?
-
您必须从数据库中获取哈希密码。您只读取“盐”值(稍后用作散列新密码的盐)
-
你在哪里设置 userSalt?和你用来存储密码的一样吗?
-
SHA256 是一个安全的哈希函数,但它不是为密码验证而设计的。密码验证应该很慢,而 SHA256 很快。请阅读this blog,其中有一节关于“修复”ASP.NET 密码散列。该部分会告诉您确切的操作。