【发布时间】:2021-12-12 01:19:20
【问题描述】:
您好,我有一个程序,我通过 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();
}
虽然当我不在数据库中散列密码时它可以工作。有什么解决办法吗?
【问题讨论】:
-
请注意,存储密码是一个难题,您几乎应该始终依赖于为您完成所有这些工作的现有框架。例如,这里你没有给你的哈希加盐。
-
@SebastianMarshall:乍一看,您似乎只是忘记在比较之前对密码进行哈希处理......?
-
您没有在登录时散列密码。而且您还应该使用参数化查询进行登录(就像您在创建用户时所做的那样)
-
你真的应该考虑一下 DavidG 所说的。试试看这个:stackoverflow.com/questions/2005054/…
-
您编写了一个客户端应用程序,客户端直接访问您的数据库。你已经输了。任何人都可以从代码库中提取数据库凭据或嗅探网络流量,并对您的数据库做任何他们想做的事情。他们可以擦除所有内容、阅读其他人的信息、插入他们自己的特权帐户,或者他们想要的任何其他内容。您需要在客户端应用程序和数据库之间有一个 API。相比之下,所有其他关于加盐或参数化查询的问题都相形见绌。