我的网站中有哈希密码功能,当用户注册时,密码会在数据库中进行哈希处理。我还设法通过哈希密码登录。但是,我添加了忘记密码功能。它的工作正常(将密码发送给用户的电子邮件),但密码仍然是哈希?你能分享哪些技巧?
这是我忘记的密码:
protected void SendEmail(object sender, EventArgs e)
{
string username = string.Empty;
string password = string.Empty;
string constr = ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("SELECT Username, [Password] FROM UserData WHERE Email = @Email"))
{
cmd.Parameters.AddWithValue("@Email", txtEmail.Text.Trim());
cmd.Connection = con;
con.Open();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
if (sdr.Read())
{
username = sdr["Username"].ToString();
password = BusinessLayer.ShoppingCart.CreateSHAHash("Password").ToString();
}
}
con.Close();
}
}
if (!string.IsNullOrEmpty(password))
{
MailMessage mm = new MailMessage("sender@gmail.com", txtEmail.Text.Trim());
mm.Subject = "Password Recovery";
mm.Body = string.Format("Hi {0},<br /><br />Your password is {1}.<br /><br />Thank You.<br/><br/>IslandGas Team", username, password);
mm.IsBodyHtml = true;
SmtpClient smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com";
smtp.EnableSsl = true;
NetworkCredential NetworkCred = new NetworkCredential();
NetworkCred.UserName = ConfigurationManager.AppSettings["UserName"];
NetworkCred.Password = ConfigurationManager.AppSettings["Password"];
smtp.UseDefaultCredentials = true;
smtp.Credentials = NetworkCred;
smtp.Port = 587;
smtp.Send(mm);
lblMessage.ForeColor = Color.Green;
lblMessage.Text = "Password has been sent to your email address.";
}
else
{
lblMessage.ForeColor = Color.Red;
lblMessage.Text = "This email address does not match our records.";
}
}
我尝试通过此代码使其工作:
using (SqlDataReader sdr = cmd.ExecuteReader())
{
if (sdr.Read())
{
username = sdr["Username"].ToString();
password = BusinessLayer.ShoppingCart.CreateSHAHash("Password").ToString();
}
}
但是在电子邮件中,它仍然是哈希。
顺便说一下,这是businesslayer中的hashpassword代码:
public static string CreateSHAHash(string Phrase)
{
SHA512Managed HashTool = new SHA512Managed();
Byte[] PhraseAsByte = System.Text.Encoding.UTF8.GetBytes(string.Concat(Phrase));
Byte[] EncryptedBytes = HashTool.ComputeHash(PhraseAsByte);
HashTool.Clear();
return Convert.ToBase64String(EncryptedBytes);
}
答案 0 :(得分:2)
向用户发送密码的能力首先打败了密码哈希的目的。这就是为什么所有具有适当设计安全性的系统都允许用户更改密码,或提供提示以提醒他们密码,但从未明确恢复他们的旧密码。
我还设法通过哈希密码登录。
这也破坏了哈希的目的,因为获得对哈希列表的访问权限使攻击者能够“合法地”在不知道密码的情况下进入系统。此外,您的系统似乎使用“unsalted”密码来生成哈希,这是一个严重的安全问题。
工作正常(将密码发送给用户的电子邮件)
老实说,我希望您的网站是为了娱乐其用户而构建的,并不会为潜在的攻击者存储任何有价值的内容。在电子邮件中发送未加密的密码与在明信片上发送秘密相同。
您可以共享的任何技巧[取消密码]
哈希的主要目的是在没有详尽搜索的情况下无法逆转。从正确构造的哈希中恢复密码需要强制解决方案,即您的系统需要破解用户密码。
使用加密强大的随机数生成器生成随机临时密码,并将该密码通过电子邮件发送给用户。将新密码设置为在几分钟内过期。让用户使用他们的临时密码登录,然后让他们立即更改密码。通过这种方式,您可以让用户通过电子邮件恢复密码而不会过多地暴露密码。
答案 1 :(得分:0)
正如gordon和dasblinkenlight已经提到的那样,重要的是要考虑哈希函数单向函数并且设计为不可恢复。 (并且对存储的密码加盐也很重要!)
要为用户启用密码恢复功能,您应该按照设置丢失的密码重置的方法。简单来说,用户输入她的电子邮件地址,系统会向用户邮寄密码重置链接。当用户点击该链接时,她将能够设置新密码。
现有解决方案可以促进这些行动。您可以将this extensive ASP.NET identity sample作为起点。
答案 2 :(得分:-1)
如果在数据库中保存用户密码的哈希值,则无法恢复密码的原始明文。这是加密哈希函数的含义。这是一种单向功能。
相反,您必须在数据库中保存纯密码或密码的加密(非散列)值。
cu gordon