vb.netsalt-cryptographypassword-encryptionstring-hashing

Password hashing - Compare 2 strings


I've just added in a function to hash and salt passwords which are stored in an Access database "Memo" field.

The hashing/salting works fine, but I can't find anything on the internet which tells me how to then decrypt them.

I did see somewhere that says you can't, but instead have to get the password from the database, then hash the entered password (for a log on screen) and compare the 2 strings. I've tried this, but the 2 strings are then different, so I cannot log in.

The algorithms for creating the hash/salt are

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

Then, when logging in, I'm trying the following

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

Am I doing something wrong? How can I compare the entered password to the encrypted password in the database?


Solution

  • The problem is you are using a random salt when hashing the entered password. Since that is different from the random salt you used when storing the hash to the DB you get different hashes.

    You have to do the following:

    1. Before storing the password to the DB create a random salt, hash the password with it and store the salt together with the password in the database
    2. When a user enters his password retrieve that user's salt from the database, use it to hash the entered password and compare the result to the hash from the database.

    Oh, and you seem to never use the password the user entered. In your code you retrieve the hash from the DB into password, hash that hash again into checkpassword and compare those. Of course you have to hash the entered password.