2015-07-19 55 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作爲起點。