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

Unk*_*ser 0 c# email hash winforms

我想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();
            }
        }
Run Code Online (Sandbox Code Playgroud)

下面的代码用于将电子邮件发送给用户:( 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);
            }
        }
Run Code Online (Sandbox Code Playgroud)

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

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

        }
Run Code Online (Sandbox Code Playgroud)

这里是设计师的的恢复形式:

在此输入图像描述

//CheckValidity button is for the check whether the e-mail is valid or
 not. //Reset button is for clear the textboxes in the form.
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

在此输入图像描述

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

更新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 ***";
Run Code Online (Sandbox Code Playgroud)

是的Password: _recoveredPassword.

我得到的hashed password是显示而不是false.

Jon*_*eet 6

散列的全部意义在于它是一种方式 - 您无法从散列中检索原始密码.

"忘记密码"功能不应该通过电子邮件发送当前密码的用户...它应该产生一个临时的"复位只有"密码(最好有一个短的过期),并通过电子邮件发送用户,链接内.然后用户跟随该链接,这允许他们将密码设置为新的"完整"密码.(你真的不希望通过电子邮件发送的"秘密"成为长期密码.)他们

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

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

  • 打败我.另一个选项虽然差别不大,但是可以向用户发送长链接,可能使用加密链接而不是临时密码.登录页面为用户提供了创建新密码的选项. (2认同)
  • @artm:是的,"加密链接"实际上相当于"临时密码",因为两者都只是发送电子邮件的临时秘密,目的是将密码重置为正确的密码. (2认同)