2015-07-19 48 views
1

我在我的网站有散列密码功能,其中当用户注册时,密码在数据库中被散列。我还设法通过散列的密码登录。但是,我添加了一个忘记密码功能。它的工作正常(发送密码给用户的电子邮件),但密码仍然散列?你可以分享的任何技巧?通过忘记密码功能解开密码

这里是我忘记密码代码:

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("[email protected]", 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); 
    } 

回答

2

向用户发送他们的密码改回失败摆在首位散列密码的目的的能力。这就是为什么所有具有合理设计安全性的系统都允许用户更改密码,或者提示他们提醒密码,但不要明确恢复其旧密码。

我也设法通过那个哈希密码登录。

这也破坏了散列的目的,因为获得对哈希列表的访问权让攻击者能够在不知道密码的情况下“合法”进入系统。此外,看起来您的系统使用“unsalted”密码来产生散列,这是一个严重的安全问题。

其工作正常(发送密码到用户的电子邮件)

我真的希望你的网站是娱乐的用户的目的而建,而不会存储任何有价值的东西给潜在攻击者。在电子邮件中发送未加密的密码与在明信片上发送秘密相同。

,你可以分享[到unhash密码]

散列的主要目的什么花招是不可能没有穷举搜索逆转。从正确构建的哈希中恢复密码需要一个强力解决方案,即您的系统需要破解用户的密码。

使用密码强的随机数生成器生成随机临时密码,并将该密码通过电子邮件发送给用户。将新密码设置为在几分钟内过期。让用户使用他们的临时密码登录,然后让他们立即更改密码。这样你就可以让用户通过电子邮件恢复密码而不会让他们暴露太多。

+0

非常丰富。会做到这一点。谢谢! –

-1

,如果你保存在数据库中的用户密码的哈希值,那么它是不可能恢复密码的原始明文。这是密码散列函数的含义。这是一个单向功能。

相反,您必须在数据库中保存普通密码或密码的加密(不散列)值。

铜戈登

+1

鼓励将密码存储为纯文本的人是绝对的nogo。 – khlr

0

正如gordon和dasblinkenlight已经提到的那样,重要的是要考虑,散列函数是单向函数并且被设计为不可恢复。 (而且它也是盐重要你存储的密码!)

启用密码恢复功能为你的用户,你应该采取的办法,以使丢失的密码可复位。简单地说,用户输入她的电子邮件地址,系统会向用户发送密码重置链接。当用户点击链接时,她可以设置一个新的密码。

现在有解决方案来促进这些行动。你可以拿this extensive ASP.NET identity sample作为起点。