C# 如何在ASP.NET MVC中设置和比较密码

C# 如何在ASP.NET MVC中设置和比较密码,c#,asp.net-mvc,authentication,cryptography,passwords,C#,Asp.net Mvc,Authentication,Cryptography,Passwords,我正在编写一个ASP.NET程序,需要将用户密码存储在数据库中。但是,当我将数据库中的密码与用户输入的密码进行比较时,发现密码不匹配。即使用户密码正确 密码哈希: string PasswordSalt = Crypto.HashPassword(DateTime.Now.ToString()); string hashPassword = Crypto.HashPassword(formcollection["PassWord"]); //Hash User PassWord user.Pas

我正在编写一个ASP.NET程序,需要将用户密码存储在数据库中。但是,当我将数据库中的密码与用户输入的密码进行比较时,发现密码不匹配。即使用户密码正确

密码哈希:

string PasswordSalt = Crypto.HashPassword(DateTime.Now.ToString());
string hashPassword = Crypto.HashPassword(formcollection["PassWord"]); //Hash User PassWord
user.PassWord = Crypto.HashPassword(PasswordSalt + hashPassword);//Add Salt to Password For Futher Security
user.PassWordSalt = PasswordSalt;
密码验证:

Users ThisUser = Users.UsersGetByEmail((string)Session["email"]);
string checkpassword = ThisUser.PassWord;

//User Inputed password.
string password = user.PassWord;

if (password != null)
{
    //Need to fix.
    string encrypt_password = Crypto.HashPassword(password);
    string salted_password = Crypto.HashPassword(ThisUser.PassWordSalt + encrypt_password);
    //bool does_password_match = Crypto.VerifyHashedPassword(checkpassword, password);
    if (checkpassword == salted_password)
    {
        //Check if the inputed password matches the password from the Database.

        //Remember to give session based on the user_id.
        Session["user_id"] = ThisUser.Id;
        return RedirectToAction("Promise");


    }
    else
    {

        ModelState.AddModelError("PassWord", "Wrong Password, Please Enter Correct Password");
        return View(user);
    }

我从未使用过它,但根据文档

Crypto.HashPassword为您添加salt,并返回一个base-64编码字符串,其中包含验证密码的所有详细信息。所以,你不需要自己加盐

您只需将哈希结果(
base64EncodedHash
如下)存储在数据库中,然后将其与VerifyHashedPassword一起使用,以便稍后进行身份验证。例如,进行如下单元测试:

var base64EncodedHash = Crypto.HashPassword("password");
Assert.IsTrue( Crypto.VerifyHashedPassword( base64EncodedHash, "password" ) );
Assert.IsFalse( Crypto.VerifyHashedPassword( base64EncodedHash, "otherPass") );

要将其转换为代码,请执行以下操作:

user.PassWord = Crypto.HashPassword(formcollection["PassWord"]);
然后进行验证(我看到为怪癖添加的注释):

理想情况下,正如我对您的错误文本所做的更改所表明的那样……无论用户名/电子邮件或密码是否错误,您都希望向用户发送相同的错误消息。如果电子邮件没有返回帐户,您的代码可能会返回不同的错误,但您不想向暴力攻击者提供那么多信息

您还需要进行一些强制检查,这样,如果他们尝试失败次数太多,就可以将该IP地址阻塞X个时间,以此类推

而且,正如有人说的…当涉及到安全问题时…直到你成为 专家…最好使用预先存在的代码/框架来减轻您的负担 风险


你有没有考虑过使用asp身份?所有这些都通过许多内置方法为您解决。规则1关于安全:不要自己构建:)我很乐意实现暴力检查。你知道怎么做吗?。谢谢你的回答。@Izuagbala,对于暴力检查,基本上你所要做的就是让他们慢下来,这样一个好的密码就需要几百年的时间才能猜出来。一个快速的谷歌应该会给你很多完整的解释。然而,简而言之:1)使DB表或缓存IpLogAttempts{Ip,AttemptScont,LastAttempts}。2) 当IP尝试登录时,如果超过最大失败/时间,请阻止它。3) 如果尚未阻止,请检查密码,如果登录错误,请增加您的尝试次数。即使封锁一个IP 5-20分钟,也会大大降低暴力攻击成功的几率。@Izuagbala,这里有一个更彻底的解释,我把它放在一起,因为评论空间不足以解释所有内容:感谢@Kelvin花时间研究这个主题。我很感激。
//Why are you storing "email" in Session before user is validated??? Seems off.
Users ThisUser = Users.UsersGetByEmail((string)Session["email"]);
string userInputPassword = user.PassWord; //this should be coming from POST

if( ThisUser != null && Crypto.VerifyHashedPassword(ThisUser.PassWord, userInputPassword) ) {
    Session["user_id"] = ThisUser.Id;
    return RedirectToAction("Promise");
}
else {
    ModelState.AddModelError("PassWord","Your username or password are incorrect");
    return View(user);
}