C# - MySQL数据库,加密后检查密码是否正确?

时间:2013-12-10 20:22:00

标签: c# php mysql encryption

我在我的程序中使用MySQL数据库,当我检查用户输入的密码是否正确时,它总是说它无效。我对电子邮件做同样的事情,但它有效。我认为这是因为我的PHP脚本在页面上创建密码时对其进行加密。这是我的代码:

        try
        {
            string command = "SELECT email FROM uc_users WHERE email = '@email';";
            string command2 = "SELECT password FROM uc_users WHERE password = '@password';";
            // CONNECTION DETAILS
            connection = new MySqlConnection(connectionString);
            connection.Open();

            // COMMAND DETAILS
            MySqlCommand email = new MySqlCommand(command, connection);
            MySqlCommand passwordc = new MySqlCommand(command2, connection);

            // PARAMETERS
            email.Parameters.AddWithValue("@email", txtEmail.Text);
            passwordc.Parameters.AddWithValue("@password", txtPassword.Text);

            // READER DETAILS
            MySqlDataReader dr;
            MySqlDataReader dr2;

            // CHECK DETAILS               
            dr = email.ExecuteReader();
            string tempE = dr.Read() ? dr.GetString(0) : "Invalid Email";
            dr.Close();
            dr2 = passwordc.ExecuteReader();
            string tempP = dr2.Read() ? dr.GetString(0) : "Invalid Password";
            dr2.Close();
            MessageBox.Show(tempE + " " + tempP);
            if (tempE == txtEmail.Text && tempP == txtPassword.Text)
            {
                connection.Close();
                tempE = "";
                tempP = "";
                string email2 = txtEmail.Text;
                frmAppHub frm = new frmAppHub(email2);
                frm.Show();
                this.Hide();
            }
            else
            {
                MessageBox.Show("Invalid login details. Please try again.");
                connection.Close();
                tempE = "";
                tempP = "";
            }
        }
        catch(MySqlException ex)
        {
            MessageBox.Show("MySQL Error - Code AHx004: " +ex.Message);
            connection.Close();
        }

任何想法怎么做?任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:2)

查询从根本上被打破。应该有一个查询,方法应该是:

// No quotes around placeholder and only ONE query that does NOT select on the password.
// If the query selects on the password then it means that the password is either
// stored as plaitext (which is not good) or the database value can be computed without
// per-user information (which is also not good).
string command = "SELECT email, password FROM uc_users WHERE email = @email";

// Only look based on the user (the email column should have a Unique constraint)
// as (although a unique salt makes it very unlikely) passwords are not unique
// nor do they identify users.
email.Parameters.AddWithValue("@email", txtEmail.Text);

// Then read the password for the given user
dr = email.ExecuteReader();
if (!dr.Read()) {
  // User not found - just stop.
  return false;
}
string dbPassword = dr.GetString(1);

return IsPasswordMatch(dbPassword, txtPassword.Text);

现在,IsPasswordMatch是一个函数,当给定数据库密码和纯文本密码时,应该通过应用所有适当的散列/盐/任何变换来确定它们是否匹配(请参阅我的第一个评论)。在任何情况下,所有逻辑都可以安全地藏在那里。

它可能看起来像:

bool IsPasswordMatch (string dbPassword, string plaintext) {
    var salt = GetSalt(dbPassword);
    var dbHash = GetHash(dbPassword);
    var ptHash = Hash(salt + plaintext);
    return dbHash == ptHash;
}

我把方法留作“高级操作”,需要适应首先使用的任何东西;但是,基本操作现在应该是显而易见的。只需重复与首先创建数据库值相同的过程 - 在两种情况下是否相同?

请务必仔细阅读using - 这样可以轻松清理资源,而不会大惊小怪。

答案 1 :(得分:0)

是的,您需要生成密码的哈希值,该密码必须与存储在数据库中的密码相同,而不是使用此哈希值而不是纯文本密码查询命令。

如果您在DB和@passowrd中有不同的字符串 - 您的结果总是无效。