[英]How to validate Password from database when password is hashed
嗨,我有一个程序,我通过 WPF 从用户那里请求用户名和密码,然后我将数据发送到存储它的数据库。
private void btnRegister_Click(object sender, RoutedEventArgs e)
{
try
{
using (SqlConnection connection = new SqlConnection(ConnectionSQL.conn))
{
SqlCommand command = new SqlCommand("INSERT INTO USERTABLE " +
"VALUES(@Username, @Password);" +
"Select SCOPE_IDENTITY();", connection);
command.Parameters.AddWithValue("@Username", txtbUsername.Text);
command.Parameters.AddWithValue("@Password", Utils.hashPassword(txtbPassword.Text));
connection.Open();
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.InsertCommand = command;
int id = Convert.ToInt32(adapter.InsertCommand.ExecuteScalar());
MessageBox.Show("User Registered! User has been added to the database: " + id);
adapter.Dispose();
String Username = txtbUsername.Text;
String Password = txtbPassword.Text;
Users temp = new Users(id, Username, Password);
Login L = new Login();
arrUsers.Add(temp);
Hide();
L.ShowDialog();
}
}
catch (SqlException ex)
{
MessageBox.Show("Error Connecting to the Database", "Connection Error" + ex.ToString());
}
}
我创建了一个函数来将密码作为哈希存储在数据库中。
public class Utils
{
public static string hashPassword(String password)
{
SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
byte[] password_bytes = Encoding.ASCII.GetBytes(password);
byte[] encrypted_bytes = sha1.ComputeHash(password_bytes);
return Convert.ToBase64String(encrypted_bytes);
}
}
当我尝试登录并验证密码时,它以散列形式存储,但它不起作用。
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
try
{
using (SqlConnection connection = new SqlConnection(ConnectionSQL.conn))
{
connection.Open();
String Username = Convert.ToString(txtbUsername.Text);
String Password = Convert.ToString(txtbPassword.Text);
String sql = "SELECT * FROM USERTABLE where Username = '" + Username + "' " +
"AND Password = '" + Password + "' ;";
SqlCommand command = new SqlCommand(sql, connection);
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
MessageBox.Show("You Have Successfully Logged In");
MainWindow Main = new MainWindow();
txtbUsername.Text = "";
txtbPassword.Text = "";
this.Hide();
Main.ShowDialog();
this.Show();
}
else
{
MessageBox.Show("Invalid Credentials");
}
reader.Close();
command.Dispose();
}
}
catch (SqlException ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadLine();
}
虽然当我不在数据库中散列密码时,它可以工作。 关于解决这个问题的任何提示?
您不会将非散列密码与散列密码进行比较。 从客户端获取密码时,您需要再次对该密码进行散列,然后匹配散列值。 如果它们匹配,它应该返回成功。
更新这个应该可以解决它:
String Password = Convert.ToString(Utils.hashPassword(txtbPassword.Text));
但是这里还有更多明显的问题需要您解决:
首先:您需要使用SqlParameter
将值添加到WHERE
子句中,而不是直接将值添加到 SQL 命令中。 这是为了避免 SQL 注入。
其次:将您的数据访问层与您的应用程序分开。 如果客户端可以使用访问数据库的代码,则这是一个很大的风险。
还有一些其他的事情我会改变。 但这些应该是很好的起点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.