Hi All,
am trying to use build a secure login page. I have written necessary functions and the registrations works fine (with secure hash + salt passwords created) but the verification never goes through. Can someone point me in the right direction?

Imports System.Data
Imports System.Data.SqlClient
Imports System.Security.Cryptography
Imports System.Web.Security

Partial Class logon
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load

    End Sub

    Private Shared Function CreateSalt(size As Integer) As String
        ' Generate a cryptographic random number using the cryptographic
        ' service provider
        Dim rng As New RNGCryptoServiceProvider()
        Dim buff As Byte() = New Byte(size - 1) {}
        rng.GetBytes(buff)

   ' Return a Base64 string representation of the random number
        Return Convert.ToBase64String(buff)
    End Function

    Private Shared Function CreatePasswordHash(pwd As String, salt As String) As String
        Dim saltAndPwd As String = [String].Concat(pwd, salt)
        Dim hashedPwd As String = FormsAuthentication.HashPasswordForStoringInConfigFile(saltAndPwd, "SHA1")
        hashedPwd = [String].Concat(hashedPwd, salt)
        Return hashedPwd
    End Function
    Private Sub storeAccountDetails(userName As String,
                          passwordHash As String)

        Dim conn As SqlConnection = New SqlConnection("Server=(local);" + "Integrated Security=SSPI;" + "database=UserAccounts")
        Dim cmd As SqlCommand = New SqlCommand("RegisterUser", conn)
        cmd.CommandType = CommandType.StoredProcedure

        Dim sqlParam As SqlParameter = Nothing

        sqlParam = cmd.Parameters.Add("@userName", SqlDbType.VarChar, 20)
        sqlParam.Value = userName


        sqlParam = cmd.Parameters.Add("@passwordHash ", SqlDbType.VarChar, 50)
        sqlParam.Value = passwordHash

        Try

            conn.Open()
            cmd.ExecuteNonQuery()

        Catch ex As Exception

            ' Code to check for primary key violation (duplicate account name)
            ' or other database errors omitted for clarity
            Throw New Exception("Exception adding account. " + ex.Message)

        Finally

            conn.Close()
        End Try
    End Sub
    Protected Sub btnRegister_Click(sender As Object, e As EventArgs) Handles btnRegister.Click
        Dim saltSize As Integer = 5
        Dim salt As String = CreateSalt(saltSize)
        Dim passwordHash As String = CreatePasswordHash(txtPassword.Text, salt)
        Try
            storeAccountDetails(txtUsername.Text, passwordHash)
            lblMessage.Text = "user registered successfully"

        Catch ex As Exception
            lblMessage.Text = ex.Message
        End Try

    End Sub
    Function verifyPassword(suppliedUsername As String, suppliedPassword As String) As Boolean



        Dim passwordMatch As Boolean = False


        ' Get the salt and pwd from the database based on the user name.

        Dim conn As SqlConnection = New SqlConnection("Server=(local);" + "Integrated Security=SSPI;" +
                                                "database=UserAccounts")

        Dim cmd As SqlCommand = New SqlCommand("LookupUser", conn)
        cmd.CommandType = CommandType.StoredProcedure


        Dim sqlParam As SqlParameter = cmd.Parameters.Add("@userName", SqlDbType.VarChar, 20)
        sqlParam.Value = suppliedUsername
        Try

            conn.Open()
            Dim reader As SqlDataReader = cmd.ExecuteReader()
            reader.Read()
            ' Return output parameters from returned data stream
    Dim dbPasswordHash As String = reader.GetString(0)
            Dim saltSize As Integer = 5
            Dim salt As String = dbPasswordHash.Substring(dbPasswordHash.Length - saltSize)
            reader.Close()

        ' Now take the password supplied by the user and generate the hash.

            Dim hashedPasswordAndSalt As String = CreatePasswordHash(suppliedPassword, salt)
            ' Now verify them.
            passwordMatch = hashedPasswordAndSalt.Equals(dbPasswordHash)

        Catch ex As Exception

            Throw New Exception("Execption verifying password. " + ex.Message)

        Finally

            conn.Close()
        End Try

        Return passwordMatch


    End Function

    Protected Sub btnSignIn_Click(sender As Object, e As EventArgs) Handles btnSignIn.Click
        Dim passwordVerified As Boolean = False
        Try
            passwordVerified = verifyPassword(txtUsername.Text, txtPassword.Text)
        Catch ex As Exception
            lblMessage.Text = ex.Message
            Return
        End Try
        If passwordVerified = True Then
            ' The user is authenticated

            lblMessage.Text = "Logon successful: User is authenticated"
        Else
            lblMessage.Text = "Invalid username or password"
        End If
    End Sub

End Class

It looks to me like your doing some extra steps when getting the salt and password out of the database.
When creating the password you create a salt, add it to the password and hash the combined string. The salt and hashed password then get saved to the database.

On signing in you retrieve the salt and hashed password but you shouldn't need to do anything to the hashed password. Add the salt to the provided password, hash it and then compare that to the hashed password in the database. If they match you're in.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.