2017-07-10 34 views
0

我已经在这里搁置了好几个小时了。我一直在尝试创建一个登录表单来开发一个简单的应用程序。c#验证存储在SQL数据库中的散列密码

我已经成功设法对salt/hash密码进行加密和创建用户帐户,登录,散列和salt都使用INSERT查询存储在SQL数据库表的不同列中。

我现在需要做的是在登录页面输入来自用户的密码,并将其与存储的盐值相结合,重组合并的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 ([email protected], [email protected], [email protected])"; 
      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盐)的用户密码输入中,以便我可以通过我的散列算法把结果,然后比较值来验证用户?

编辑:感谢弗拉德Stryapko的答案我能够得到它通过使用稍微修改后的版本工作,并已成功实施散列算法,一切工作,因为它应该。 所以正确/最有帮助的答案应该发给他。

string ds = @"Data Source"; 
using (SqlConnection con = new SqlConnection(ds)) 
{ 
string query = "SELECT Salt FROM [Table] WHERE ([email protected])"; 
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); 
    }  
} 
+0

究竟是什么不明显?你已经很准确地描述了算法。你有从数据库读取的问题?将阅读结果与文本框结合起来有问题吗? –

+0

嘿谢谢你的回应,我的问题是,我无法弄清楚如何从数据库中获取盐的价值,并将它与文本框中的输入相结合,就像你提到的那样。我知道我需要用算法实现的过程,但实际上从数据库中提取数据对我来说很麻烦。关于我需要做什么来实现这一点的任何建议? – lostintranslation

+0

请检查我的答案,看看它是否有帮助。 –

回答

0

这里是你如何能得到盐,根据您当前的代码:

string ds = @"Data Source"; 
using (SqlConnection con = new SqlConnection(ds)) 
{ 
    string query = "SELECT Salt FROM [Table] WHERE ([email protected])"; 
    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]; 
     }  
    } 
} 

以后你可以使用盐将它传递给你的散列函数。

+0

谢谢弗拉德,已经实现了这一点,它除了一个部分,我改变了 如果(reader.Read())) salt = reader [0]; } 我代替: 如果(dr.Read()){ 盐 = dr.GetString(0) } 你肯定把我在正确的轨道上,虽然,我现在已经有散列函数和登录工作完全与您的帮助。非常感谢你! – lostintranslation

+0

很高兴帮助您,请将答案标记为已接受,以表明问题已解决。 –

2

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

您需要将您的实现更改为首先查询salt,然后计算散列,然后再查询一次以将计算出的散列与存储的散列进行比较。

对于给出相同输出的散列,密码和盐必须相同。作为一个方面说明,您可能应该使用PBKDF2或Bcrypt,而不是像SHA或MD5这样的简单哈希。

+0

嗨,谢谢你的回应,我知道字符串@Salt是错误的,这是我最后努力的一部分(不成功)。 我试图拉第一个查询盐的价值,但我不确定如何实现这一点。这是通过使用Sqldatareader完成的吗?什么是需要得到盐的查询,所以我可以用它来计算散列? – lostintranslation

相关问题