Thursday 21 March 2013

Validating users using password, hash and salt


DB Fields:
Table User: Columns (UserName, Password, Salt)


Public Shared Function GetPasswordHash(Password As String, Salt As String) As String
Dim StringEncoder As New UTF8Encoding()
Dim Bytes_Password As Byte() = StringEncoder.GetBytes(Password)
Dim Bytes_Salt As Byte() = StringEncoder.GetBytes(Salt)

' Array for password & salt
Dim Bytes_Password_Salt As Byte() = New Byte(Bytes_Password.Length + Bytes_Salt.Length - 1) {}

For i As Integer = 0 To Bytes_Password.Length - 1
    Bytes_Password_Salt(i) = Bytes_Password(i)
Next

For i As Integer = 0 To Bytes_Salt.Length - 1
      Bytes_Password_Salt(i + Bytes_Password.Length) = Bytes_Salt(i)
Next

Dim MD5Provider As New MD5CryptoServiceProvider
Dim Bytes_Hash As Byte() = MD5Provider.ComputeHash(Bytes_Password_Salt)
Dim String_Hash As String = Convert.ToBase64String(Bytes_Hash)

Return String_Hash
End Function

Public Shared Function ValidateUser(UserName As String, Password As String) As Boolean
Dim IsValidUser As Boolean = False

Dim Cmd As New SqlCommand()
Cmd.CommandText = "SELECT [Password] PassHash, Salt AS Salt FROM [User] WHERE UPPER(UserName) = UPPER(@UserName) "
Cmd.CommandType = Data.CommandType.Text

Cmd.Parameters.AddWithValue("UserName", UserName)

Dim ds As DataSet = DBHelper.RunSQLQuery(Cmd)

Dim StoredHash As String = Nothing
Dim StoredSalt As String = Nothing
If ds.Tables.Count = 1 Then
    If ds.Tables(0).Rows.Count = 1 Then

       Dim CurrentRow As DataRow = ds.Tables(0).Rows(0)
       If Not IsDBNull(CurrentRow("PassHash")) Then
               StoredHash = CurrentRow("PassHash")
        End If

       If Not IsDBNull(CurrentRow("Salt")) Then
                StoredSalt = CurrentRow("Salt")
       End If
   End If
End If

If Not IsNothing(StoredHash) And Not IsNothing(StoredSalt) Then
   Dim CalculatedHash As String = GetPasswordHash(Password, StoredSalt)
   If CalculatedHash = StoredHash Then
        IsValidUser = True
   End If
End If

Return IsValidUser
End Function


Public Shared Function RunSQLQuery(ByVal Cmd As SqlCommand) As System.Data.DataSet
Dim s As New System.Data.DataSet()

Cmd.Connection = New SqlConnection(ConnectionString)
Dim a As New System.Data.SqlClient.SqlDataAdapter(Cmd)
a.Fill(s)

Return s
End Function

No comments:

Post a Comment