简体   繁体   中英

C# - MySQL Database, Check password is correct when it's encrypted?

I'm using a MySQL database with my program and when I check if the password a user enters is correct, it always says it's invalid. I do the same with email but it works. I think it's because my PHP script encrypts the password when it's created on the page. Here is my code:

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

Any ideas how to do it? Any help is appreciated.

The query is fundamentally broken. There should be one query and the approach should be like:

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

Now, IsPasswordMatch is a function which, when, given the database password and the plain-text password, should determine if they are a match by applying all the appropriate hash/salt/whatever transforms (see my first comment). In any case, all the logic can be safely tucked away in there.

It might look something like:

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

I've left in the methods as "high level operations" that need to be adapted to whatever was used in the first place; however, the basic operation should now be apparent. Just repeat the same process as was used to create the database value in the first place - is it the same in both cases?

Make sure to read up on using as well - this will enable resources to be cleaned up easily without fuss.

Yes, you need to generate hash of your password, that must be identical stored in database and than query your command with this hash, instead of plain text password.

If you have different strings in DB and @passowrd - you always have invalid result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM