如何在asp.net Identity中使用指定的salt和密码生成哈希?

时间:2014-02-13 16:28:39

标签: c# asp.net hash asp.net-identity owin

我目前正在使用新的ASP.NET Identity框架。

我必须实现一种检查用户是否希望将密码更改为过去使用的密码的方法。我有一张包含退役哈希及其相应盐的表格。

我无法弄清楚如何使用特定的盐生成哈希,以便我可以将新密码与已退役的密码进行比较。我见过 UserManager.PasswordHasher.HashPassword(密码)但是我没有看到指定盐的重载。

如何使用Identity散列密码并指定盐?

3 个答案:

答案 0 :(得分:5)

只需验证密码的方式与目前验证的密码相同。您需要做的就是在旧密码中存储您为当前密码存储的相同信息,并检查它们是否都无法验证

bool UserReusedPassword(string username, string password)
{
    foreach(string oldHash in GetOldHashesForUser(username)
    {
        if(UserManager.PasswordHasher.VerifyHashedPassword(oldHash, password) != PasswordVerificationResult.Failed)
        {
            return true;
        }
    }

    return false;
}

使用UserManager.PasswordHasher盐被存储为散列字符串的前几个字节,因此您不需要“手动输入盐”VerifyHashedPassword将自动读入并将其设置为验证过程。

答案 1 :(得分:4)

您不能使用特定的盐。但是,您应该为每个密码使用不同的盐。 因此,您的HashPassword方法负责生成盐。这是一个例子(主要受到Mircosoft默认实现的启发):

public string HashPassword(string password) 
{ 
    if (password == null) throw new ArgumentNullException("password"); 

    int saltSize = 16;
    int iterations = 4000;

    byte[] salt; 
    byte[] bytes; 

    using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, saltSize, iterations)) 
    { 
        salt = rfc2898DeriveBytes.Salt; 
        bytes = rfc2898DeriveBytes.GetBytes(32); 
    } 

    byte[] inArray = new byte[saltSize + 32];       
    Buffer.BlockCopy((Array)salt, 0, (Array)inArray, 0, saltSize); 
    Buffer.BlockCopy((Array)bytes, 0, (Array)inArray, saltSize, 32); 
    return Convert.ToBase64String(inArray); 
} 

正如您所看到的,盐嵌入在HashPassword方法的结果中,因此当您需要验证密码时,您可以提取salt和哈希并进行验证。

答案 2 :(得分:0)

您可以查看从SQL成员身份到身份here的迁移示例。 SQL成员资格使用密码salt进行加密,文章概述了在自定义密码中挂钩以重用这些密码。