我在我的程序中使用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();
}
任何想法怎么做?任何帮助表示赞赏。
答案 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中有不同的字符串 - 您的结果总是无效。