c#验证存储在SQL数据库中的散列密码

时间:2017-07-10 11:44:43

标签: c# sql login

我已经被困了几个小时了。我一直在尝试为我正在开发的简单应用创建一个登录表单。

我已成功设法对密码进行salt / hash,并且在创建用户帐户时,使用INSERT查询将登录,哈希和salt全部存储在SQL数据库表的单独列中。

我现在需要做的是从登录页面的用户输入密码并将其与存储的salt值合并,重新组合组合的pw + salt并将它们与存储的哈希值进行比较以验证用户。我正在使用SELECT查询来尝试实现这一点,但到目前为止一直没有成功。

这是我的代码:

///Gather the data from the SQL db, find the username, hash and salt values
        string ds = @"Data Source";
        using (SqlConnection con = new SqlConnection(ds))
        {

///define a set of strings for the query, the login textbox, password textbox and the Hash Gen Algorithm
            string query = "SELECT Login, Hash, Salt FROM [Table] WHERE (Login=@Login, Hash=@Hash, Salt=@Salt)";
            string uname = logTXT.Text;
            string passw = pwTXT.Text;
            string hash = GenHash(passw, "@salt");

            using (SqlCommand cmd = new SqlCommand(query, con))
            {
                con.Open();

                cmd.Parameters.AddWithValue("@Login", uname);
                cmd.Parameters.AddWithValue("@Hash", hash);

                cmd.Connection = con;
                SqlDataReader dr = cmd.ExecuteReader();

                if("@Hash" == hash)
                {
                    MessageBox.Show("Login Successful");
                }
                else
                {
                    MessageBox.Show("Login Failed");
                }


            }
        }

我不确定如何成功实现这一目标。

我的问题是:如何获取存储密码salt的SQL列的值,然后将其添加到文本框中的用户密码输入(pwTXT.Text +存储的pw salt),这样我就可以结果通过我的哈希算法,然后比较值来验证用户?

编辑:感谢Vlad Stryapko的回答,我能够通过使用稍微修改过的版本来实现它并成功实现了散列算法,并且一切正常。 所以正确/最有帮助的答案应该归他所有。

string ds = @"Data Source";
using (SqlConnection con = new SqlConnection(ds))
{
string query = "SELECT Salt FROM [Table] WHERE (Login=@Login)";
string uname = logTXT.Text;              

using (SqlCommand cmd = new SqlCommand(query, con))
{
    con.Open();    
    cmd.Parameters.AddWithValue("@Login", uname);
    SqlDataReader dr = cmd.ExecuteReader();   
    string salt = null;
    if (dr.Read())
    {
        salt = dr.GetString(0);
    }    
}

2 个答案:

答案 0 :(得分:2)

GenHash()函数正在传递字符串" @ salt"而不是实际的盐。

您需要将实现更改为第一个查询salt,然后计算哈希值,然后再次查询以将计算的哈希值与存储的哈希值进行比较。

对于提供相同输出的哈希,密码和salt必须相同。

作为旁注,您可能应该使用PBKDF2或Bcrypt而不是像SHA或MD5这样的简单哈希。

答案 1 :(得分:0)

以下是根据您当前的代码获取盐的方法:

string ds = @"Data Source";
using (SqlConnection con = new SqlConnection(ds))
{
    string query = "SELECT Salt FROM [Table] WHERE (Login=@Login)";
    string uname = logTXT.Text;              

    using (SqlCommand cmd = new SqlCommand(query, con))
    {
        con.Open();    
        cmd.Parameters.AddWithValue("@Login", uname);
        SqlDataReader dr = cmd.ExecuteReader();   
        string salt = null;
        if (reader.Read())
        {
            salt = reader[0];
        }    
    }
}

稍后您可以使用salt将其传递给散列函数。