【问题标题】:C#,asp.net Passwords are not matching after hashing with saltC#,asp.net 用盐散列后密码不匹配
【发布时间】:2015-02-13 14:03:33
【问题描述】:

我使用了带盐的散列作为密码。在我实施散列之前,我有一个存储过程,用于检查文本框值与数据库中的值,代码工作正常。在实施散列后,虽然密码不匹配,我检查了数据库中的哈希值和我输入的密码,两者都是相同的。我在谷歌中查找,有人建议在数据库中手动输入密码值会导致问题。所以我创建了一个用户注册表单并在那里对密码进行哈希处理并将其存储在数据库中。谁能指导我哪里出错了。

我的登录页面代码:

 using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Configuration;
    using System.Data.SqlClient;
    using System.Data;
    using System.Security.Cryptography;

    namespace taxiservices
    {
        public partial class adminlogin : System.Web.UI.Page
        {
            String Salt;
            String Hash;
            String Pwd;
            protected void Page_Load(object sender, EventArgs e)
            {

            }

            public string SaltedHash(string password)
            {
                Salt = "salthashtestsalthashtestsalthashtestsalthashtestsalthashtestsalthashtestsalthashtestsalthashtest";
                Hash = ComputeHash(Salt, password);
                return Hash;

            }

            static string ComputeHash(string salt, string password)
            {
                var saltBytes = Convert.FromBase64String(salt);
                using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, saltBytes, 1000))
                    return Convert.ToBase64String(rfc2898DeriveBytes.GetBytes(256));
            }

            public static bool Verify(string salt, string hash, string password)
            {
                return hash == ComputeHash(salt, password);
            }

            protected void Button1_Click(object sender, EventArgs e)
            {
                Session["username"] = username.Text.ToString();
                 Pwd=SaltedHash(password.Text.ToString());
                 Response.Write(Pwd);
                string query;
                string ConnectionStringnew = ConfigurationManager.ConnectionStrings["ConnectionStringName"].ConnectionString;
                using (SqlConnection con = new SqlConnection(ConnectionStringnew))
                {
                    query = "Emplogin";   //stored procedure Name
                    SqlCommand com = new SqlCommand(query, con);
                    com.CommandType = CommandType.StoredProcedure;
                    com.Parameters.AddWithValue("@Usename", username.Text.ToString());   //for username 
                    com.Parameters.AddWithValue("@Password",Pwd);  //for password

                    con.Open();

                    int usercount = (Int32)com.ExecuteScalar();// for taking single value
                    con.Close();
                    if (usercount == 1)  // comparing users from table 
                    {

                        Session["user"] = "valid";

                        Response.Redirect("adminhomepage.aspx");  //for sucsseful login
                    }
                    else
                    {

                        Label2.Text = "Invalid User Name or Password";  //for invalid login
                    }



                }
            }

            protected void username_TextChanged(object sender, EventArgs e)
            {

            }
        }
    }

用户创建密码的页面:

 using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Security.Cryptography;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

namespace taxiservices
{
    public partial class changepassword : System.Web.UI.Page
    {
        String Salt;
        String Hash;
        protected void Page_Load(object sender, EventArgs e)
        {


        }

        protected void TextBox2_TextChanged(object sender, EventArgs e)
        {

        }
        public string SaltedHash(string password)
        {
            Salt="salthashtestsalthashtestsalthashtestsalthashtestsalthashtestsalthashtestsalthashtestsalthashtest";
            Hash = ComputeHash(Salt, password);
            return Hash;
        }

        static string ComputeHash(string salt, string password)
        {
            var saltBytes = Convert.FromBase64String(salt);
            using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, saltBytes, 1000))
                return Convert.ToBase64String(rfc2898DeriveBytes.GetBytes(256));
        }

        protected void Button1_Click(object sender, EventArgs e)
        {

            string Pwd = SaltedHash(TextBox2.Text);
            string ConnectionStringn = ConfigurationManager.ConnectionStrings["ConnectionStringName"].ConnectionString;
            using (SqlConnection con = new SqlConnection(ConnectionStringn))
            {
                using (SqlCommand cmd = new SqlCommand("INSERT INTO Users(Username,Password) VALUES(@User,@password)"))
                {
                    cmd.Connection = con;
                    cmd.Parameters.AddWithValue("@User", TextBox3.Text);
                    cmd.Parameters.AddWithValue("@password", Pwd);
                    con.Open();
                    cmd.ExecuteNonQuery();
                    con.Close();

                }
            }
        }
    }
}

存储过程:

    Create  procedure Emplogin
(
@Usename Varchar (20),
@Password varchar (10)
)
as
Begin
Select COUNT(*)from Users where username=@Usename and password=@Password 
End

【问题讨论】:

  • 您在存储过程中只使用了 10 个字符作为加盐密码——这是故意的吗?你的Users 表结构是什么/
  • 不是因为你在 Emplogin 过程中的@Password 参数是 varachar(10)。你的盐哈希密码肯定超过 10,所以你传递给程序的可能只是前 10 个字符,这就是它不匹配的原因。
  • 谢谢 TZHX,PrzemG 我做了更改,现在工作正常。我不是故意忘记看到那部分 TZHX
  • 如果您不介意,还有一件事,这是我的代码,我想为我正在制作的网站投入现场制作,可以吗,像安全一样吗?编码是否足够好放在一个实时网站上。

标签: c# asp.net hash salt


【解决方案1】:

当您将详细信息传递给您的 Emplogin 存储过程时,它只会获取您的加盐密码的前 10 个字符(它会截断其他 246 个字符)。当它根据您的 Users 数据库检查这十个字符的字符串时,它没有找到匹配项。

您应该调整Emplogin 过程,使@Password 变量的长度与Users 表中password 列的长度相匹配。

【讨论】:

  • 如果您不介意,还有一件事,这是我的代码,我想为我正在制作的网站投入现场制作,可以吗,像安全一样吗?编码是否足够好放在实时网站上?
  • 好吧,既然你这么说......是的......它对于一个实时网站来说已经足够了......只需对你的编码添加一些调整,一切都应该没问题......