Search code examples
c#hashpasswordsforgot-password

Unhash the password through forgot password feature


I have the hash password feature in my website wherein when user registers, the password is hashed in the database. I also managed to log in through that hashed password. However, i added a forgot password feature. its working fine(sending the password to the users email) but the password is still hashed? any tricks that you can share?

Here is my forgot password code:

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.";
        }
    }

i tried to make it work by this code:

using (SqlDataReader sdr = cmd.ExecuteReader())
                {
                    if (sdr.Read())
                    {
                        username = sdr["Username"].ToString();
                        password = BusinessLayer.ShoppingCart.CreateSHAHash("Password").ToString();
                    }
                }

but in the email, its still hashed.

by the way here is my hashpassword code in the businesslayer:

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);
    }

Solution

  • An ability to send users their password back defeats the purpose of hashing the password in the first place. That is why all systems with properly designed security let users change password, or give hints to remind them of the password, but never explicitly recover their old password.

    I also managed to log in through that hashed password.

    This defeats the purpose of hashing, too, because obtaining access to a list of hashes gives an attacker a way to enter the system "legally" without knowing the password. Moreover, it appears that your system uses "unsalted" passwords to produce hash, which is a serious security problem.

    its working fine (sending the password to the users email)

    I honestly hope that your web site is built for purposes of entertaining its users, and does not store anything of value to potential attackers. Sending unencrypted passwords in an e-mail is the same as sending secrets on postcards.

    any tricks that you can share [to unhash the password]

    The main purpose of hash is to be impossible to reverse without an exhaustive search. Recovering a password from a properly constructed hash calls for a brute-force solution, i.e. your system needs to crack your user's password.

    Generate a random temporary password using cryptographically strong random number generator, and e-mail that password to the user. Set the new password to expire within a few minutes. Let users login with their temporary password, and then ask them to change their password immediately. This way you would let users recover password through e-mail without exposing them too much.