如何将字符串值与哈希值进行比较?

时间:2016-08-24 11:38:26

标签: c# asp.net api asp.net-web-api

我创建了一个API控制器,用于比较我输入的用户名和密码与保存在我的数据库中的用户名和密码(HASHED)。

我的问题是我真的很难比较我输入的密码,因为我的数据库上的密码处于HASH状态。他们显然会有两个不同的价值观。如何将我的字符串值与哈希值进行比较?

如果两个密码匹配,则应返回' true'否则是假的。 我现在处于一个令人困惑的阶段。希望您能够帮助我。感谢。

这些是我使用的代码。

LoginController.cs

namespace WebFormsDemo.Controllers
{
    public class LoginController : ApiController
    {
        private EBMSEntities db = new EBMSEntities();

        // GET: api/Login           
        [Route("api/Login/Search/{username}/{password}")]
        [ResponseType(typeof(List<AspNetUser>))]    
        public bool getUserPassword(string username, string password)       
        {              
            var hashedPassword = "";
            hashedPassword = Crypto.HashPassword(password);    

            var user = (from u in db.AspNetUsers
                                     where u.UserName.Equals(username)
                                     && u.PasswordHash.Equals(hashedPassword)
                                     select u).ToList();    

            if (user.Count() != 0)
            {
                return true;
            }    
            return false;    
        }    
    }
}

3 个答案:

答案 0 :(得分:1)

提供了多种技术来散列密码字符串。其中一些是MD5,SHA1,SHA256等等,甚至包含复杂的功能代码,以确保密码不易恢复到字符串。现在,问题可能您正在使用错误版本的散列算法。

我宁愿将此代码留给ASP.NET成员资格本身,Validation类对象中有一个函数Membership,可用于要求ASP.NET验证用户是否是有效。然后,您的代码会喜欢这个,

public bool getUserPassword(string username, string password)       
{              
    return Membership.ValidateUser(username, password); 
}

这将由ASP.NET本身管理,你会得到你想要的!如果没有,那么我建议检查哈希算法并确保,您使用的是用于散列初始用户密码的相同哈希算法。否则,它将永远不同。

对于ASP.NET Identity,您可以使用UserManager.CheckPassword(user, password)来确定密码对用户是否正确。由于ASP.NET Identity是推荐的框架(并且Membership是较旧的框架),因此建议使用以下代码使用UserManager.Find执行此操作(用户:

public bool getUserPassword(string username, string password) {
    var user = UserManager.Find(username, password);
    return user == null; // If user is null, password didn't match.
}

这样,你就可以做到这一点。最后,您可以在MSDN文档中找到有用且有用的材料,以便全面了解这些功能。

答案 1 :(得分:0)

从下面的评论回答:

  

先生实际上我并不知道MVC 5的哈希算法,但那是我正在使用的。

听起来你正在使用Asp.Net Identity。在这种情况下,您应该使用提供的框架,包括UserManager和/或SignInManager来验证凭据。

<击> 首先返回用户,然后比较内存中的密码。这比在数据库上更容易。

var doesPasswordMatch = false;

var user = db.AspNetUsers.SingleOrDefault(x => x.UserName == username);
if(user != null)
{
    var hashedPassword = Crypto.HashPassword(password);
    // var doesPasswordMatch = //compare u.PasswordHash with hashedPassword in memory
}
return doesPasswordMatch;

您仍然需要将持久密码转换为相同的格式。目前还不清楚这是一个字节数组还是其他东西。最好的选择是将其抽象为不同的实用程序类。还不清楚你如何哈希密码(算法是什么)。确保使用带盐的安全散列技术(根据散列密码而变化)。

答案 2 :(得分:-1)

对从用户收到的密码应用相同的散列函数。然后,您可以比较两个散列密码。如果它们相同,那么密码是正确的。

由于您使用的是身份,因此可以使用UserManager.PasswordHasher.VerifyHashedPassword()。您需要将数据库中的散列密码作为第一个参数发送,并将用户指定的密码作为第二个参数发送。

public bool getUserPassword(string username, string password)       
{   
    string hashPassword= (from u in db.AspNetUsers
                        where u.UserName.Equals(username)
                        select u.PasswordHash).ToString();
    //Get the salt from the hashed password and use it to hash the user given password
    //Then verify that both the passwords match and check the result with the PasswordVerificationResult enum
    if (UserManager.PasswordHasher.VerifyHashedPassword(hashPassword, password) != PasswordVerificationResult.Failed)
        return true;
    else
        return false;
}

VerifyHashedPassword返回类型PasswordVerificationResult,这是一个枚举,可用于检查给定密码是否失败或通过验证。

如果您只想让用户登录,则可以使用SignInManager.PasswordSignIn()SignInManager.PasswordSignInAsync()方法。两种方法都具有相同的签名