更改后无法识别散列密码
Hashed password is not recognized after changing it
我已经在 registration.aspx 中输入了我的密码。在我的业务层中包含此代码:
public static string CreateSHAHash(string Phrase)
{
SHA512Managed HashTool = new SHA512Managed();
Byte[] PhraseAsByte = System.Text.Encoding.UTF8.GetBytes(string.Concat(Phrase));
Byte[] EncryptedBytes = HashTool.ComputeHash(PhraseAsByte);
HashTool.Clear();
return Convert.ToBase64String(EncryptedBytes);
}
注册页面中的代码:
scm.Parameters.AddWithValue("@Password", BusinessLayer.ShoppingCart.CreateSHAHash(txtPW.Text));
有了上面的代码,密码在数据库中被散列,当我用这个代码登录时它工作正常:
protected void btn_Login_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString);
conn.Open();
string checkuser = "select count(*) from UserData where Username = '" + txtUser.Text + "'";
SqlCommand scm = new SqlCommand(checkuser, conn);
int temp = Convert.ToInt32(scm.ExecuteScalar().ToString());
conn.Close();
if (temp == 1)
{
conn.Open();
string checkPassword = "select Password from UserData where Username ='" + txtUser.Text + "'";
SqlCommand passCom = new SqlCommand(checkPassword, conn);
string password = passCom.ExecuteScalar().ToString();
if (password == BusinessLayer.ShoppingCart.CreateSHAHash(txtPassword.Text))
{
Session["New"] = txtUser.Text;
Response.Write("<script>alert('Logged In')</script>");
Response.Redirect("OrderNow.aspx");
}
else
{
lblcrederror.Text = ("Credentials dont match");
}
}
else
{
lblcrederror.Text = ("Credentials dont match");
}
然而,当我在 changepassword.aspx
中使用此代码更改它时,它不让我输入新密码。
protected void btn_update_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(conn);
con.Open();
str = "select * from UserData ";
com = new SqlCommand(str, con);
SqlDataReader reader = com.ExecuteReader();
while (reader.Read())
{
if (BusinessLayer.ShoppingCart.CreateSHAHash(txt_cpassword.Text) == reader["Password"].ToString())
{
up = 1;
}
}
reader.Close();
con.Close();
if (up == 1)
{
con.Open();
str = "update UserData set Password=@Password where UserName='" + Session["New"].ToString() + "'";
com = new SqlCommand(str, con);
com.Parameters.Add(new SqlParameter("@Password", SqlDbType.VarChar, 50));
com.Parameters["@Password"].Value = BusinessLayer.ShoppingCart.CreateSHAHash(txt_npassword.Text);
com.ExecuteNonQuery();
con.Close();
lbl_msg.Text = "Password changed Successfully";
}
else
{
lbl_msg.Text = "Please enter correct Current password";
}
}
我在这里错过了什么?
检查 50 是否截断了哈希值。
com.Parameters.Add(new SqlParameter("@Password", SqlDbType.VarChar, 50));
在旁注中,我看到您的解决方案对 SQL 注入非常开放。
"select Password from UserData where Username ='" + txtUser.Text + "'";
用户可以在文本框中写入 sql 语句,劫持您的数据库,创建自己的表或删除整个数据库。您应该始终参数化查询。我看到您对 Update 语句执行了此操作,但您应该考虑对所有变量执行此操作。
这会很快创建大量代码,因此我也会考虑制作一个 SQL 包装器,将您重复的所有内容包装起来。完成重构后,它可能看起来像这样:
var sql = new SqlWrapper("select Password from UserData where Username = @username", txtUser.Text);
var dataSet = sql.Execute();
然后您可以将所有连接字符串、命令++隐藏在这个包装器后面,只告诉包装器您真正关心的是什么。
您还应该考虑使用盐作为密码。如果你和我有相同的密码,哈希值将是相同的。盐可以解决这个问题。
一篇关于密码安全的好文章 -> https://crackstation.net/hashing-security.htm
我已经在 registration.aspx 中输入了我的密码。在我的业务层中包含此代码:
public static string CreateSHAHash(string Phrase)
{
SHA512Managed HashTool = new SHA512Managed();
Byte[] PhraseAsByte = System.Text.Encoding.UTF8.GetBytes(string.Concat(Phrase));
Byte[] EncryptedBytes = HashTool.ComputeHash(PhraseAsByte);
HashTool.Clear();
return Convert.ToBase64String(EncryptedBytes);
}
注册页面中的代码:
scm.Parameters.AddWithValue("@Password", BusinessLayer.ShoppingCart.CreateSHAHash(txtPW.Text));
有了上面的代码,密码在数据库中被散列,当我用这个代码登录时它工作正常:
protected void btn_Login_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString);
conn.Open();
string checkuser = "select count(*) from UserData where Username = '" + txtUser.Text + "'";
SqlCommand scm = new SqlCommand(checkuser, conn);
int temp = Convert.ToInt32(scm.ExecuteScalar().ToString());
conn.Close();
if (temp == 1)
{
conn.Open();
string checkPassword = "select Password from UserData where Username ='" + txtUser.Text + "'";
SqlCommand passCom = new SqlCommand(checkPassword, conn);
string password = passCom.ExecuteScalar().ToString();
if (password == BusinessLayer.ShoppingCart.CreateSHAHash(txtPassword.Text))
{
Session["New"] = txtUser.Text;
Response.Write("<script>alert('Logged In')</script>");
Response.Redirect("OrderNow.aspx");
}
else
{
lblcrederror.Text = ("Credentials dont match");
}
}
else
{
lblcrederror.Text = ("Credentials dont match");
}
然而,当我在 changepassword.aspx
中使用此代码更改它时,它不让我输入新密码。
protected void btn_update_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(conn);
con.Open();
str = "select * from UserData ";
com = new SqlCommand(str, con);
SqlDataReader reader = com.ExecuteReader();
while (reader.Read())
{
if (BusinessLayer.ShoppingCart.CreateSHAHash(txt_cpassword.Text) == reader["Password"].ToString())
{
up = 1;
}
}
reader.Close();
con.Close();
if (up == 1)
{
con.Open();
str = "update UserData set Password=@Password where UserName='" + Session["New"].ToString() + "'";
com = new SqlCommand(str, con);
com.Parameters.Add(new SqlParameter("@Password", SqlDbType.VarChar, 50));
com.Parameters["@Password"].Value = BusinessLayer.ShoppingCart.CreateSHAHash(txt_npassword.Text);
com.ExecuteNonQuery();
con.Close();
lbl_msg.Text = "Password changed Successfully";
}
else
{
lbl_msg.Text = "Please enter correct Current password";
}
}
我在这里错过了什么?
检查 50 是否截断了哈希值。
com.Parameters.Add(new SqlParameter("@Password", SqlDbType.VarChar, 50));
在旁注中,我看到您的解决方案对 SQL 注入非常开放。
"select Password from UserData where Username ='" + txtUser.Text + "'";
用户可以在文本框中写入 sql 语句,劫持您的数据库,创建自己的表或删除整个数据库。您应该始终参数化查询。我看到您对 Update 语句执行了此操作,但您应该考虑对所有变量执行此操作。
这会很快创建大量代码,因此我也会考虑制作一个 SQL 包装器,将您重复的所有内容包装起来。完成重构后,它可能看起来像这样:
var sql = new SqlWrapper("select Password from UserData where Username = @username", txtUser.Text);
var dataSet = sql.Execute();
然后您可以将所有连接字符串、命令++隐藏在这个包装器后面,只告诉包装器您真正关心的是什么。
您还应该考虑使用盐作为密码。如果你和我有相同的密码,哈希值将是相同的。盐可以解决这个问题。
一篇关于密码安全的好文章 -> https://crackstation.net/hashing-security.htm