验证输入的用户密码是否与登录页面c#asp.net上数据库中的哈希密码匹配
本文关键字:密码 数据库 net 哈希 c#asp 用户 输入 是否 验证 登录 | 更新日期: 2023-09-27 18:22:51
我有一个登录页面,用户可以在其中输入用户名和密码,这两个信息都存储在数据库中。用户名以纯文本形式存储,但密码以带salt的哈希密码形式存储在MySQL数据库中。我使用了来自crackstation网站的C#代码示例和Chris Duran的youtube视频。我成功地注册了用户,并将他们的密码散列并存储在MySQL数据库中。
我有一个简单的登录页面,其中有一个用于显示电子邮件地址的文本框和一个用于用户必须输入的密码的文本框。我的登录按钮有一个点击事件。我的登录页面代码后面的代码如下:
protected void btnlogin_Click(object sender, System.EventArgs e)
{
char activation;
if(Request.QueryString["tokenNum"] != null)
{
using (OdbcConnection dbConnection = new OdbcConnection(srlsConnStr))
{
dbConnection.Open();
{
OdbcCommand dbCommand = new OdbcCommand();
dbCommand.Connection = dbConnection;
dbCommand.CommandText = @"SELECT tokenNum FROM srlsLogin WHERE user_email_pk = ? and user_password = ?;";
dbCommand.Parameters.AddWithValue("@user_email_pk", txtUsername.Text);
dbCommand.Parameters.AddWithValue("@user_password", txtPassword.Text);
dbCommand.ExecuteNonQuery();
OdbcDataReader dataReader = dbCommand.ExecuteReader();
while (dataReader.Read())
{
if ( token == dataReader["tokenNum"].ToString())
{
updateActivationStatus(txtUsername.Text);
userRedirect(txtUsername.Text, txtPassword.Text);
}
else
{
test.Text = "You are not authorized to login! Please activate your account following the activation link sent to your email " + txtUsername.Text + " !";
}
}
dataReader.Close();
}
dbConnection.Close();
}
}
}
protected void updateActivationStatus(string email)
{
using (OdbcConnection dbConnection = new OdbcConnection(srlsConnStr))
{
dbConnection.Open();
{
OdbcCommand dbCommand = new OdbcCommand();
dbCommand.Connection = dbConnection;
dbCommand.CommandText = @"UPDATE srlsLogin set activation_status = 'Y' WHERE user_email_pk = ?;";
dbCommand.Parameters.AddWithValue("@user_email_pk", txtUsername.Text);
dbCommand.ExecuteNonQuery();
}
dbConnection.Close();
}
}
//Redirecting the user to correct page
protected void userRedirect(string username, string passcode)
{
Session["username"] = txtUsername.Text;
Session["password"] = txtPassword.Text;
//Session["password"] = PasswordHash.ValidatePassword(txtPassword.Text, "@slowhashsalt");
using (OdbcConnection dbConnection = new OdbcConnection(srlsConnStr))
{
dbConnection.Open();
{
OdbcCommand dbCommand1 = new OdbcCommand();
dbCommand1.Connection = dbConnection;
dbCommand1.CommandText = @"SELECT user_status FROM srlsLogin WHERE user_email_pk = ? and user_password = ?;";
dbCommand1.Parameters.AddWithValue("@user_email_pk", txtUsername.Text);
dbCommand1.Parameters.AddWithValue("@user_password", txtPassword.Text);
dbCommand1.ExecuteNonQuery();
OdbcDataReader dataReader1 = dbCommand1.ExecuteReader();
while (dataReader1.Read())
{
user_status = dataReader1["user_status"].ToString();
Session["userType"] = user_status;
}
if (user_status == "Participant")
{
Response.Redirect("/srls/StudentUser");
}
else if (user_status == "Coordinator")
{
Response.Redirect("/srls/CoordinatorUser");
}
dataReader1.Close();
}
dbConnection.Close();
}
}
private void LoginWithPasswordHashFunction()
{
List<string> salthashList = null;
List<string> usernameList = null;
try
{
using (OdbcConnection dbConnection = new OdbcConnection(srlsConnStr))
{
dbConnection.Open();
{
OdbcCommand dbCommand = new OdbcCommand();
dbCommand.Connection = dbConnection;
dbCommand.CommandText = @"SELECT user_email_pk, slowsalthash FROM srlslogin WHERE user_email_pk = ?;";
dbCommand.Parameters.AddWithValue("@user_email_pk", txtUsername.Text);
dbCommand.ExecuteNonQuery();
OdbcDataReader dataReader = dbCommand.ExecuteReader();
while (dataReader.HasRows && dataReader.Read())
{
if (salthashList == null)
{
salthashList = new List<string>();
usernameList = new List<string>();
}
string saltHashes = dataReader.GetString(dataReader.GetOrdinal("@slowhashsalt"));
salthashList.Add(saltHashes);
string userName = dataReader.GetString(dataReader.GetOrdinal("@user_email_pk"));
usernameList.Add(userName);
}
dataReader.Close();
if (salthashList != null)
{
for (int i = 0; i < salthashList.Count; i++)
{
bool validUser = PasswordHash.ValidatePassword(txtPassword.Text, salthashList[i]);
if (validUser == true)
{
Session["username"] = usernameList[i];
Response.BufferOutput = true;
Response.Redirect("/srls/", false);
}
else
{
lblMessage.Text = "User not authorized! Please try again!";
}
}
}
}
dbConnection.Close();
}
}
catch (Exception ex)
{
}
}
我对C#和asp.net有点陌生,对如何使用会话["密码"]感到困惑,我知道,如果我将纯文本版本的密码存储到数据库表中,它可以正常工作,但我希望使用Session["password"]来对照哈希密码进行检查,这样当用户将文本密码放入表中时,就可以对照哈希密码进行检查,并让用户进入他们的帐户。
这是旧代码,可能有更新或降级??你基本上已经获取了值,看看它是否匹配,我所有的Using都会获取这两个字符串,这样你就可以将该部分更新到你的DB调用中
public bool VerifyPassword(string suppliedUserName, string suppliedPassword)
{
try
{
string dbPasswordHash = string.Empty;
string salt = string.Empty;
using (SqlDataReader reader = DB.drProc("LookupUser", new SqlParameter[] {
DB.Parameter("@userName", SqlDbType.VarChar, 255, suppliedUserName) }))
{
reader.Read();
dbPasswordHash = reader.GetString(0);
salt = reader.GetString(1);
}
string passwordAndSalt = string.Concat(suppliedPassword, salt);
string hashedPasswordAndSalt = FormsAuthentication.HashPasswordForStoringInConfigFile(passwordAndSalt, "SHA1");
return hashedPasswordAndSalt.Equals(dbPasswordHash);
}
catch (Exception)
{
return false;
}
}
尽量不要将用户密码存储在会话中。这就是你能做的。一旦用户输入用户名和密码并单击登录页面的登录按钮,就可以对密码进行哈希处理并将其传递给存储过程。您将这个散列密码与数据库中的密码进行检查,如果一切正常,则向代码发送一个返回变量,说明用户已通过身份验证。然后将其存储在会话中。
更改此行
dbCommand.Parameters.AddWithValue("@user_password", txtPassword.Text);
至
dbCommand.Parameters.AddWithValue("@user_password", PasswordHasher(txtPassword.Text));
假设你有一个名为PasswordHasher的函数,它接受一个字符串并返回其哈希版本。事实上,在代码中任何使用密码进行任何操作的地方,你都不应该使用密码,你应该立即将其转换为哈希版本。
我能够让我的代码正常工作。感谢所有帮助我解决问题的人。我在下面发布了我的解决方案,以防将来有人遇到类似的问题,并可以将其作为参考。
protected void btnlogin_Click(object sender, System.EventArgs e)
{
char activation;
if (Request.QueryString["tokenNum"] != null)
{
using (OdbcConnection dbConnection = new OdbcConnection(srlsConnStr))
{
dbConnection.Open();
{
OdbcCommand dbCommand = new OdbcCommand();
dbCommand.Connection = dbConnection;
dbCommand.CommandText = @"SELECT tokenNum FROM login WHERE useremail = ?";
dbCommand.Parameters.AddWithValue("@useremail", txtUsername.Text);
dbCommand.ExecuteNonQuery();
OdbcDataReader dataReader = dbCommand.ExecuteReader();
while (dataReader.Read())
{
if (token == dataReader["tokenNum"].ToString())
{
updateActivationStatus(txtUsername.Text);
LoginWithPasswordHashFunction();
}
else
{
test.Text = "You are not authorized to login! Please activate your account following the activation link sent to your email " + txtUsername.Text + " !";
}
}
}
dbConnection.Close();
}
}
else if (Request.QueryString["tokenNum"] == null)
{
using (OdbcConnection dbConnection = new OdbcConnection(srlsConnStr))
{
dbConnection.Open();
{
OdbcCommand dbCommand1 = new OdbcCommand();
dbCommand1.Connection = dbConnection;
dbCommand1.CommandText = @"SELECT * FROM login WHERE useremail = ?;";
dbCommand1.Parameters.AddWithValue("@useremail", txtUsername.Text);
dbCommand1.ExecuteNonQuery();
OdbcDataReader dataReader1 = dbCommand1.ExecuteReader();
if (dataReader1.Read())
{
activation = Convert.ToChar(dataReader1["activation_status"]);
if (activation == 'Y')
{
LoginWithPasswordHashFunction();
}
else
{
lblMessage.Text = "Please activate your account following the Activation link emailed to you at <i>" + txtUsername.Text + "</i> to Continue!";
}
}
else
{
lblMessage.Text = "Invalid Username or Password";
}
dataReader1.Close();
}
dbConnection.Close();
}
}
}
private void LoginWithPasswordHashFunction()
{
List<string> salthashList = null;
List<string> usernameList = null;
try
{
using (OdbcConnection dbConnection = new OdbcConnection(srlsConnStr))
{
dbConnection.Open();
{
OdbcCommand dbCommand = new OdbcCommand();
dbCommand.Connection = dbConnection;
dbCommand.CommandText = @"SELECT slowhashsalt, useremail FROM login WHERE useremail = ?;";
dbCommand.Parameters.AddWithValue(@"useremail", txtUsername.Text);
OdbcDataReader dataReader = dbCommand.ExecuteReader();
while (dataReader.HasRows && dataReader.Read())
{
if (salthashList == null)
{
salthashList = new List<string>();
usernameList = new List<string>();
}
string saltHashes = dataReader.GetString(dataReader.GetOrdinal("slowhashsalt"));
salthashList.Add(saltHashes);
string userInfo = dataReader.GetString(dataReader.GetOrdinal("useremail"));
usernameList.Add(userInfo);
}
dataReader.Close();
if (salthashList != null)
{
for (int i = 0; i < salthashList.Count; i++)
{
bool validUser = PasswordHash.ValidatePassword(txtPassword.Text, salthashList[i]);
if (validUser == true)
{
Session["useremail"] = usernameList[i];
OdbcCommand dbCommand1 = new OdbcCommand();
dbCommand1.Connection = dbConnection;
dbCommand1.CommandText = @"SELECT userstatus FROM login WHERE useremail = ?;";
dbCommand1.Parameters.AddWithValue("@useremail", txtUsername.Text);
dbCommand1.ExecuteNonQuery();
OdbcDataReader dataReader1 = dbCommand1.ExecuteReader();
while (dataReader1.Read())
{
user_status = dataReader1["userstatus"].ToString();
Session["userType"] = user_status;
}
Response.BufferOutput = true;
if (user_status == "Participant")
{
Response.Redirect("/StudentUser", false);
}
else if (user_status == "Coordinator")
{
Response.Redirect("/CoordinatorUser", false);
}
else if (user_status == "Instructor")
{
Response.Redirect("/InstructorUser", false);
}
else if (user_status == "Coordinator/Instructor")
{
Response.Redirect("/CoordinatorInstructorUser", false);
}
dataReader1.Close();
Response.Redirect(/StudentUser) - Goes to Login Page";
}
else
{
lblMessage.Text = "Invalid Username or Password! Please Try Again!";
}
}
}
}
dbConnection.Close();
}
}
catch (Exception ex)
{
}
}
protected void updateActivationStatus(string email)
{
using (OdbcConnection dbConnection = new OdbcConnection(srlsConnStr))
{
dbConnection.Open();
{
OdbcCommand dbCommand = new OdbcCommand();
dbCommand.Connection = dbConnection;
dbCommand.CommandText = @"UPDATE login set activation_status = 'Y' WHERE useremail = ?;";
dbCommand.Parameters.AddWithValue("@useremail", txtUsername.Text);
dbCommand.ExecuteNonQuery();
}
dbConnection.Close();
}
}