C# 如何检查输入的密码是否等于存储的密码?

C# 如何检查输入的密码是否等于存储的密码?,c#,asp.net,asp.net-core,C#,Asp.net,Asp.net Core,假设我在用户面板中实现了更改密码的方法。在进行更改之前,我要求用户输入当前密码,实际上我创建了以下方法: [HttpPost] [ValidateAntiForgeryToken] public bool CheckCurrentPassword(string username, string password) { var originalUser = _userManager.Users.FirstOrDefault(c => c.UserName == username);

假设我在用户面板中实现了更改密码的方法。在进行更改之前,我要求用户输入当前密码,实际上我创建了以下方法:

[HttpPost]
[ValidateAntiForgeryToken]
public bool CheckCurrentPassword(string username, string password)
{
    var originalUser = _userManager.Users.FirstOrDefault(c => c.UserName == username);
    var hash = _userManager.PasswordHasher.HashPassword(originalUser, password);

    if (hash == originalUser.PasswordHash)
        return true;

    return false;
}
本质上,我向这个方法发送
用户名
,这是一个唯一的字段,我可以检索请求更改密码的用户。我还获得了新密码的哈希值,然后将哈希值与数据库中存储的哈希值进行比较

问题是散列是不同的。我不知道为什么,但使用相同的密码,我有两个不同的散列(一个存储在db中),另一个由该方法动态生成


也许有另一种方法可以检查当前密码是否与输入的密码相同?

如果哈希值不同,则在将密码输入数据库之前用于哈希的方法必须不同于
\u userManager.PasswordHasher.HashPassword
。真想不出任何其他解释。看看您是否能够匹配这两种散列方式。

我也遇到了这个问题,这是因为在MVC项目中进行的散列在某种程度上受到SQL数据库的操纵,所以这种方式(如下所示)在比较输入的密码和SQL数据库中的现有密码时,我是如何设法解决哈希密码不匹配的问题的

您可以尝试使用稍微不同的方式将输入的密码与现有密码进行比较

public ActionResult Login(UserLogin login)
{

  var v = dc.Users.Where(a => a.UserEmailAddress == login.UserEmailAddress).FirstOrDefault();

  if(string.Compare(Crypto.Hash(login.UserPassword), v.UserPassword) == 0)
  {
     //do login here
  }
}
因此,如果您将控制器设置为接受表单中的登录详细信息,则可以使用“登录”在您试图登录的数据库中查找用户。在查询中找到该用户后,您可以继续执行“string.Compare”

我希望这能有所帮助。

这正是它的用途:

当您使用时,最好使用获取您的
原始用户
。整个功能可以变成:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<bool> CheckCurrentPassword(string username, string password)
{
    var originalUser = await _userManager.FindByNameAsync(username);

    // originalUser might be null (as in your example), so check for that accordingly.

    return await _userManager.CheckPasswordAsync(originalUser, password);
}
[HttpPost]
[ValidateAntiForgeryToken]
公共异步任务CheckCurrentPassword(字符串用户名、字符串密码)
{
var originalUser=await_userManager.FindByNameAsync(用户名);
//originalUser可能为null(如您的示例中所示),因此请相应地检查它。
返回wait\u userManager.CheckPasswordAsync(原始用户,密码);
}
使用
Async
方法需要调用代码使用
Async/await
,我已将其折叠到上面的示例中。行动支持这一开箱即用;处理
任务的返回类型


如果您对
CheckPasswordAsync
函数的实现方式感兴趣,您可以在中亲自查看,这可能有助于确定您自己的版本不起作用的原因。

哈希函数可能会加入一些随机“salt”-当您两次调用HashPassword时,您可能会得到不同的哈希值。谢谢Kirk!非常感谢你的帮助。你能给我推荐一本学习ASP.NET核心的好资源或书吗?没问题。我发现对于ASP.NET核心来说,一般来说,是一个很好的资源;特别是基础部分。
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<bool> CheckCurrentPassword(string username, string password)
{
    var originalUser = await _userManager.FindByNameAsync(username);

    // originalUser might be null (as in your example), so check for that accordingly.

    return await _userManager.CheckPasswordAsync(originalUser, password);
}