从数据库中检索散列密码到文本

时间:2014-10-30 07:20:11

标签: c# winforms email hash

我想在程序中执行Forgot your password?,我已经可以检索从数据库中散列的用户名和密码并将其发送给电子邮件用户(我使用自己的电子邮件作为用户),但是我我上传的电子邮件仍然是实际存储在数据库中的哈希密码(不是实际存储在密码之前的密码),一旦我无法弄清楚如何检索实际密码而我得到的是假(布尔值)或者哈希密码。

你们能帮助我吗?

以下是我正在使用的代码:

以下代码用于检索信息: (SystemManager类)

public static void RecoverMember(string _value1, string _selectedIndex, string _value2, Form _windowsForm, TextBox _windowsTextBox)
        {
            using (OleDbConnection connection = new OleDbConnection(connectionString))
            {
                string query = "SELECT * FROM [Member] WHERE [Email] = @Email";

                connection.Open();

                using (OleDbCommand command = new OleDbCommand(query, connection))
                {
                    command.Parameters.Add("@Email", OleDbType.VarChar);
                    command.Parameters["@Email"].Value = _value1;

                    using (OleDbDataReader reader = command.ExecuteReader())
                    {
                        if (reader.Read())
                        {
                            UserInformation.FirstName = (string)reader["FirstName"];
                            UserInformation.LastName = (string)reader["LastName"];
                            UserInformation.Name = (string)reader["Username"];

                            string securityQuestion = (string)reader["SecurityQuestion"];
                            string securityAnswer = (string)reader["SecurityAnswer"];
                            string password = (string)reader["Password"];

                            _isValidRecoverSecurityQuestion = BCrypt.ValidateHash(_selectedIndex, securityQuestion);
                            _isValidRecoverSecurityAnswer = BCrypt.ValidateHash(_value2, securityAnswer);
                            _recoveredPassword = BCrypt.ValidateHash(password, password);

                            UserInformation.Password = Convert.ToString(_recoveredPassword);

                            if (_isValidRecoverSecurityQuestion && _isValidRecoverSecurityAnswer)
                            {
                                Authenticate _authenticate = new Authenticate();

                                _authenticate.ShowDialog();

                                ShowMessageBox("Your credentials has been sent to your email.", "Success", 2);

                                SendRecoverCredentials(_value1);

                                _windowsForm.Hide();

                                _windowsForm.Close();
                            }

                        }

                        if (!_isValidRecoverSecurityQuestion || !_isValidRecoverSecurityAnswer)
                        {
                            Authenticate _authenticate = new Authenticate();

                            _authenticate.ShowDialog();

                            ShowMessageBox("Either your email, security question or answer incorrect. Please try again.", "Error", 1);

                            ClearTextBoxes(_windowsForm.Controls);

                            _windowsTextBox.Focus();
                        }

                        reader.Close();
                    }
                }

                connection.Close();
            }
        }

以下代码用于将电子邮件发送给用户: (SystemManager类)

public static void SendRecoverCredentials(string _to)
        {
            try
            {
                SmtpClient _smtp = new SmtpClient();

                MailMessage _message = new MailMessage();

                _message.From = new MailAddress("credentialhelper@gmail.com", "SIA - Point of Sales - Support -");
                _message.To.Add(new MailAddress(_to, UserInformation.FirstName + " " + UserInformation.LastName));
                _message.Subject = "Credentials Recover";
                _message.Body = "Dear " + UserInformation.FirstName + " " + UserInformation.LastName + "," +
                    "\n\n\nBelow are your credentials:" + "\n\n\n\n" + "Username: " + UserInformation.Name + "\nPassword: " + UserInformation.Password +
                    "\n\n\n\nTo avoid for the future message been moved to the spam or junk folder, please add credentialhelper@gmail.com to be your contact list." +
                    "\n\n\n*** This is an automatically computer generated message, please do not reply to this message ***";

                _smtp.Port = 587;
                _smtp.Host = "smtp.gmail.com";
                _smtp.EnableSsl = true;
                _smtp.UseDefaultCredentials = false;
                _smtp.Credentials = new NetworkCredential("credentialhelper@gmail.com", "(the password does not shown in here)");

                _smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
                _smtp.Send(_message);

                ShowMessageBox("Your message has been successfully sent.", "Success", 2);
            }

            catch (Exception ex)
            {
                ShowMessageBox("Message : " + ex + "\n\nEither your e-mail or password incorrect. (Are you using Gmail account?)", "Error", 1);
            }
        }

以下是我用它的地方:(恢复表格)

// button1_Click is for the Submit button

void button1_Click(object sender, EventArgs e)
        {
            if (this.textBox1.Text == string.Empty || string.IsNullOrWhiteSpace(this.textBox1.Text))
            {
                SystemManager.ShowMessageBox("E-mail required.", "Information", 2);
            }

            else if (_isCheckedEmail != true)
            {
                SystemManager.ShowMessageBox("You have to check the validity of your e-mail before proceed.", "Information", 2);
            }

            else if (this.textBox2.Text == string.Empty || string.IsNullOrWhiteSpace(this.textBox2.Text))
            {
                SystemManager.ShowMessageBox("Security Answer required.", "Information", 2);
            }

            else
            {   // textBox1 is for the e-mail field
                // comboBox1 is for the security question field
                // textbox2 is for the security answer field

                SystemManager.RecoverMember(this.textBox1.Text, this.comboBox1.Text, this.textBox2.Text, this, this.textBox1);
            }

        }

以下是 恢复表单的 设计师

enter image description here

//CheckValidity button is for the check whether the e-mail is valid or
 not. //Reset button is for clear the textboxes in the form.

这是数据库图像以及电子邮件:

enter image description here

enter image description here

很抱歉长篇大论。我非常感谢你的回答。非常感谢你。

更新1:

如果我从

更改Password: UserInformation.Password
_message.Body = "Dear " + UserInformation.FirstName + " " + UserInformation.LastName + "," +
                        "\n\n\nBelow are your credentials:" + "\n\n\n\n" + "Username: " + UserInformation.Name + "\nPassword: " + UserInformation.Password +
                        "\n\n\n\nTo avoid for the future message been moved to the spam or junk folder, please add credentialhelper@gmail.com to be your contact list." +
                        "\n\n\n*** This is an automatically computer generated message, please do not reply to this message ***";

Password: _recoveredPassword

我得到的是hashed password而不是false

2 个答案:

答案 0 :(得分:6)

哈希的全部意义在于它是一种方式 - 你无法从哈希中检索原始密码。

“忘记了密码”功能不应该将现有密码通过电子邮件发送给用户......它应该生成一个临时的“仅重置”密码(理想情况下是短期到期)并发送电子邮件 在链接中向用户提供。然后用户跟随该链接,这允许他们将密码设置为新的“完整”密码。 (你真的不希望通过电子邮件发送的“秘密”是长期密码。)他们

通过电子邮件发送任何敏感信息的事实在某种程度上是不理想的......如果这是针对非常敏感的数据,您不希望该电子邮件本身足以改变密码(或登录) - 如果它与用户请求重置链接时显示的页面上的浏览器上显示的某些代码组合会更好。然后是双因素身份验证和各种其他安全选项...但至少,重置链接是一个开始。

永远不会通过电子邮件发送用户自己输入的密码的纯文本版本。 (当其他网站执行此操作时,我会非常交叉。)虽然许多用户知道他们不应该在多个网站上使用相同的密码,但他们通常仍然这样做 - 所以如果该电子邮件被拦截,你就会只是将他们的帐户置于您的网站上,但也可能存在其他网站。

答案 1 :(得分:1)

哈希是一种单向操作。我们无法从我们拥有的哈希值中获取原始字符串。这就是为什么我们应该在处理登录流时比较哈希值(存储在db中的哈希值和用户输入的哈希值之间)。