密码哈希 - 比较 2 个字符串
Password hashing - Compare 2 strings
我刚刚添加了一个函数来散列和加盐密码,这些密码存储在 Access 数据库 "Memo" 字段中。
hashing/salting 工作正常,但我在互联网上找不到任何告诉我如何解密它们的信息。
我确实看到某处说你不能,而是必须从数据库中获取密码,然后散列输入的密码(用于登录屏幕)并比较 2 个字符串。我已经试过了,但是两个字符串不同,所以我无法登录。
创建 hash/salt 的算法是
Public Shared Function createRandomSalt() As String
Dim mix As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!£$%^&*()-_=+{}][@'~#:;?/>.<,\|"
Dim salt As String = ""
Dim rnd As New Random
Dim sb As New StringBuilder
For i As Integer = 1 To 50
Dim x As Integer = rnd.Next(0, mix.Length - 1)
salt &= (mix.Substring(x, 1))
Next
Return salt
End Function
Public Shared Function Hash512(ByVal password As String, ByVal salt As String)
Dim convertedToBytes As Byte() = Encoding.UTF8.GetBytes(password & salt)
Dim hashType As HashAlgorithm = New SHA512Managed()
Dim hashBytes As Byte() = hashType.ComputeHash(convertedToBytes)
Dim hashedResult As String = Convert.ToBase64String(hashBytes)
Return hashedResult
End Function
然后,在登录时,我正在尝试以下操作
sql = "SELECT * FROM [Users] WHERE [User_ID] = ?"
Dim sCmd As New OleDb.OleDbCommand(sql, mainDBconnection)
sCmd.Parameters.Add("@ID", OleDb.OleDbType.VarChar).Value = txtUser.Text
mainDBadapter = New OleDb.OleDbDataAdapter(sCmd)
mainDBset = New DataSet
mainDBadapter.Fill(mainDBset)
For Each userRow In mainDBset.Tables(0).Rows
Dim password As String = ""
password = mainDBset.Tables(0).Rows(0).Item("Password")
Dim checkPassword As String = (frmSystemSettings.Hash512(password, frmSystemSettings.createRandomSalt))
If userRow.Item("User_ID") = txtUser.Text And password = checkPassword Then
我是不是做错了什么?如何将输入的密码与数据库中的加密密码进行比较?
问题是您在对输入的密码进行哈希处理时使用了随机盐。由于这与将哈希存储到数据库时使用的随机盐不同,因此您会得到不同的哈希。
您必须执行以下操作:
- 在将密码存储到数据库之前创建一个随机盐,用它散列密码并将盐与密码一起存储在数据库中
- 当用户输入他的密码时,从数据库中检索该用户的 salt,使用它对输入的密码进行哈希运算,并将结果与数据库中的哈希值进行比较。
哦,而且您似乎从来没有使用过用户输入的密码。在您的代码中,您将数据库中的散列检索到 password
,然后将该散列再次散列到 checkpassword
中并进行比较。当然你必须对输入的密码进行哈希处理。
我刚刚添加了一个函数来散列和加盐密码,这些密码存储在 Access 数据库 "Memo" 字段中。
hashing/salting 工作正常,但我在互联网上找不到任何告诉我如何解密它们的信息。
我确实看到某处说你不能,而是必须从数据库中获取密码,然后散列输入的密码(用于登录屏幕)并比较 2 个字符串。我已经试过了,但是两个字符串不同,所以我无法登录。
创建 hash/salt 的算法是
Public Shared Function createRandomSalt() As String
Dim mix As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!£$%^&*()-_=+{}][@'~#:;?/>.<,\|"
Dim salt As String = ""
Dim rnd As New Random
Dim sb As New StringBuilder
For i As Integer = 1 To 50
Dim x As Integer = rnd.Next(0, mix.Length - 1)
salt &= (mix.Substring(x, 1))
Next
Return salt
End Function
Public Shared Function Hash512(ByVal password As String, ByVal salt As String)
Dim convertedToBytes As Byte() = Encoding.UTF8.GetBytes(password & salt)
Dim hashType As HashAlgorithm = New SHA512Managed()
Dim hashBytes As Byte() = hashType.ComputeHash(convertedToBytes)
Dim hashedResult As String = Convert.ToBase64String(hashBytes)
Return hashedResult
End Function
然后,在登录时,我正在尝试以下操作
sql = "SELECT * FROM [Users] WHERE [User_ID] = ?"
Dim sCmd As New OleDb.OleDbCommand(sql, mainDBconnection)
sCmd.Parameters.Add("@ID", OleDb.OleDbType.VarChar).Value = txtUser.Text
mainDBadapter = New OleDb.OleDbDataAdapter(sCmd)
mainDBset = New DataSet
mainDBadapter.Fill(mainDBset)
For Each userRow In mainDBset.Tables(0).Rows
Dim password As String = ""
password = mainDBset.Tables(0).Rows(0).Item("Password")
Dim checkPassword As String = (frmSystemSettings.Hash512(password, frmSystemSettings.createRandomSalt))
If userRow.Item("User_ID") = txtUser.Text And password = checkPassword Then
我是不是做错了什么?如何将输入的密码与数据库中的加密密码进行比较?
问题是您在对输入的密码进行哈希处理时使用了随机盐。由于这与将哈希存储到数据库时使用的随机盐不同,因此您会得到不同的哈希。
您必须执行以下操作:
- 在将密码存储到数据库之前创建一个随机盐,用它散列密码并将盐与密码一起存储在数据库中
- 当用户输入他的密码时,从数据库中检索该用户的 salt,使用它对输入的密码进行哈希运算,并将结果与数据库中的哈希值进行比较。
哦,而且您似乎从来没有使用过用户输入的密码。在您的代码中,您将数据库中的散列检索到 password
,然后将该散列再次散列到 checkpassword
中并进行比较。当然你必须对输入的密码进行哈希处理。