我有一个登录页面,用户可以在其中输入用户名和密码,这些用户名和密码都存储在数据库中。用户名存储为纯文本,但密码存储为散列密码,在MySQL数据库中带有salt。我使用了来自crackstation website的C#代码示例和来自Chris Duran的youtube video。我成功地注册了用户并获取了他们的密码进行哈希并存储在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 [“密码”]感到困惑,我知道如果我将密码的纯文本版本存储到数据库表中它工作正常,但我想使用会话[“密码”]来检查散列密码,以便当用户输入文本密码时,可以根据表中的散列密码检查它,并让用户进入他们的帐户。
答案 0 :(得分:1)
这是旧代码,也许有更新或解压?你基本上抓住你已经拥有的值,看看它是否匹配,所有我使用它会抓住两个字符串,所以你可以将那个部分更新为你的数据库调用
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;
}
}
答案 1 :(得分:0)
尽量不要在会话中存储用户密码。这就是你能做的。 用户输入用户名和密码并单击登录页面的登录按钮后,您可以散列密码并将其传递给存储过程。 您使用数据库中的密码检查此哈希密码,如果一切正常,则将返回变量发送回代码,说明用户已通过身份验证。然后,您将其存储在会话中。
答案 2 :(得分:0)
更改此行
dbCommand.Parameters.AddWithValue("@user_password", txtPassword.Text);
要
dbCommand.Parameters.AddWithValue("@user_password", PasswordHasher(txtPassword.Text));
假设你有一个名为PasswordHasher的函数,它接受一个字符串并返回它的散列版本。实际上,在您的代码中,如果您使用密码执行任何操作,则不应使用密码,应立即将其转换为散列版本。
答案 3 :(得分:0)
我能够让我的代码正常运行。感谢所有帮助我解决问题的人。我将在下面发布我的解决方案,以防将来有人遇到类似的问题,并可以将其作为参考。
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();
}
}