2011-10-03 64 views
2

我使用的是相同的功能,登陸時哈希值進行比較,因爲我來散列密碼,當用戶註冊:散列出了錯

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 

據我所看到的,在散列我在這裏所做的沒有什麼區別。

有沒有人有任何想法?

+0

供參考:[「在密碼驗證的典型用法中,** salt與單向函數**的輸出一起存儲」](http://en.wikipedia.org/wiki/Salt_ %28cryptography%29) – AakashM

+0

也[此安全SE](http://security.stackexchange.com/questions/3272/password-hashing-add-salt-pepper-or-is-salt-enough)和鏈接從它 – AakashM

回答

3
  1. 當你插入到表中創建一個帳戶,您使用txtName.Text的用戶名,但檢查你正在使用txtUser.Text的憑據時。
  2. 你爲什麼使用隨機鹽?每種加密的鹽都不一樣?我將你的代碼粘貼到一個新項目中,當我連續兩次運行Compute方法獲得相同的密碼時,我得到了兩個不同的結果......顯然這是行不通的。嘗試傳遞鹽值而不是Nothing,並使用相同的鹽來創建帳戶和比較登錄。下面是一些工作示例代碼:

    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 and pass2 are identical 
    

希望這有助於!

+0

編號用戶註冊和用戶登錄在不同的頁面上處理。只是控制名稱不同而已。 – Ortund

+0

@Logan:看我的編輯。我已經添加了另一點:-) – mellamokb

+0

我設置了一個8的靜態鹽大小,仍然沒有運氣。不錯的建議,雖然 – Ortund

2

除非我錯過了它(對語言不太熟悉),否則不會將鹽存儲在任何地方。

您必須使用您在創建驗證帳戶時使用的鹽。

在旁註:您可以爲每個用戶帳戶生成一個隨機salt或爲所有帳戶使用固定salt。這兩種方法都適用。第一種理論上更安全,但如果鹽足夠長,兩者都適用於實際目的。