我使用相同的函数在登录期间散列值进行比较,就像在用户注册时散列密码一样:
Public Shared Function Compute(ByVal text As String, ByVal algorithm As String, Optional ByVal salt() As Byte = Nothing) As String
If salt Is Nothing Then
Dim saltSize As Integer = 8
salt = New Byte(saltSize - 1) {}
Dim rng As New RNGCryptoServiceProvider
rng.GetNonZeroBytes(salt)
End If
Dim textBytes As Byte() = Encoding.UTF8.GetBytes(text)
Dim saltedTextBytes() As Byte = New Byte(textBytes.Length + salt.Length - 1) {}
For i As Integer = 0 To textBytes.Length - 1
saltedTextBytes(i) = textBytes(i)
Next i
For i As Integer = 0 To salt.Length - 1
saltedTextBytes(textBytes.Length + i) = salt(i)
Next i
Dim hash As HashAlgorithm
If algorithm Is Nothing Then
algorithm = ""
End If
Select Case algorithm.ToUpper
Case "SHA1" : hash = New SHA1Managed
Case "SHA256" : hash = New SHA256Managed
Case "SHA384" : hash = New SHA384Managed
Case "SHA512" : hash = New SHA512Managed
Case Else : hash = New MD5CryptoServiceProvider
End Select
Dim hashBytes As Byte() = hash.ComputeHash(saltedTextBytes)
Dim saltedHash() As Byte = New Byte(hashBytes.Length + salt.Length - 1) {}
For i As Integer = 0 To hashBytes.Length - 1
saltedHash(i) = hashBytes(i)
Next i
For i As Integer = 0 To salt.Length - 1
saltedHash(hashBytes.Length + i) = salt(i)
Next i
Dim hashValue As String = Convert.ToBase64String(saltedHash)
Return Left(hashValue, 36)
End Function我的问题是,当我尝试登录一个帐户时,其密码已被此函数散列,散列值不匹配。我想我是跳过了一步或别的什么。
下面是创建用户帐户的代码:
' The email address needs to be valid
Dim pattern As String = "^(?("")("".+?""@)|(([0-9a-zA-Z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-zA-Z])@))(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,6}))$"
Dim match As Match = Regex.Match(txtEmail.Text, pattern)
If match.Success Then
'Hash the user's password before entering it into the database.
Dim pass As String = Crypt.Compute(txtPass.Text, "SHA512", Nothing)
' Enter the information from the form into the database.
Dim sql As String = "INSERT INTO Users(Username, Password, EmailAddress) " & _
"VALUES(@User, @Pass, @Email)"
Dim cmd As New SqlCommand(sql, conn)
cmd.Parameters.AddWithValue("@User", txtName.Text)
cmd.Parameters.AddWithValue("@Pass", pass)
cmd.Parameters.AddWithValue("@Email", txtEmail.Text)
conn.Open()
cmd.ExecuteNonQuery()
conn.Close()
Else
lblError.Text = "Invalid email address. Please correct."
lblError.ForeColor = Drawing.Color.Red
End If这里没有包含的更多检查与我的问题无关。
这是我的用户登录:
Dim pass As String = Crypt.Compute(txtPass.Text, "SHA512", Nothing)
Dim UserData As New DataSet
Dim UserAdapter As New SqlDataAdapter
UserAdapter.SelectCommand = New SqlCommand("SELECT * FROM Users " & _
"WHERE Username = @User AND Password = @Pass", conn)
UserAdapter.SelectCommand.Parameters.AddWithValue("@User", txtUser.Text)
UserAdapter.SelectCommand.Parameters.AddWithValue("@Pass", pass)
UserAdapter.Fill(UserData)
If UserData.Tables(0).Rows.Count <> 1 Then
lblError.Text = "Invalid username or password."
lblError.ForeColor = Drawing.Color.Red
Session("LoginAttempt") = CInt(Session("LoginAttempt")) + 1
Else
Session("LoggedIn") = True
Response.Redirect("Home.aspx")
End If据我所知,我在这里所做的散列没有什么不同。
有谁有什么想法吗?
发布于 2011-10-03 22:53:40
当您通过向表中插入来创建帐户时,您将使用txtUser.Text.
Compute方法时,我得到了两个不同的结果……显然这是行不通的。尝试传入Salt值而不是Nothing,并使用相同的salt创建帐户和比较登录。以下是一些有效的示例代码:Dim thePass As String = "MyPassword“Dim theSalt As String = "salt”Dim pass As String = Compute(thePass,"SHA512",Encoding.UTF8.GetBytes(theSalt)) Console.WriteLine(pass) Dim pass2 As String = Compute(thePass,"SHA512",Encoding.UTF8.GetBytes(theSalt)) Console.WriteLine( pass2 ) 'pass和pass2是相同的
希望这能有所帮助!
发布于 2011-10-03 22:57:55
除非我错过了它(不是很熟悉这门语言),否则你不会把盐放在任何地方。
您必须使用与创建帐户时相同的盐来进行验证。
附注:您可以为每个用户帐户生成一个随机盐,也可以为所有帐户使用一个固定的盐。这两种方法都有效。第一种方法在理论上更安全,但如果盐足够长,两种方法在实际应用中都是可以的。
https://stackoverflow.com/questions/7636629
复制相似问题