Storing the hashed password in database is successful. But when verifying if the input password and the hash stored in database, it always returning false.
Dim pw As String = txt_password.Text
Dim salt As String = BCrypt.Net.BCrypt.GenerateSalt(12)
Dim hash As String = BCrypt.Net.BCrypt.HashPassword(pw, salt)
Dim Reader As MySqlDataReader = sqlLogin.ExecuteReader()
If (BCrypt.Net.BCrypt.Verify(pw, hash)) Then
MessageBox.Show("Login Succesful!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Information)
ElseIf Reader.HasRows = False Then
MessageBox.Show("Invalid Login Information!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
txt_username.Text = ""
txt_password.Text = ""
Especially when it comes to encryption, you ought to have some general idea of the principles and concepts involved. Salted Password Hashing explains common pitfalls and makes a number of recommendations (one is
BCrypt, so you may be on the right path).
It looks like you are not reading the stored hash from the DB before you verify. You don't show how it is saved, but that is important in order for it to verify.
' cuts down on dot operators Imports BCryptor = BCrypt.Net.BCrypt
' new user save Dim sql = "INSERT INTO userlogin (email, username, pwhash) VALUES (@email, @n, @pw)" ' prep: Dim salt = BCryptor.GenerateSalt(12) ' == 2^12 Dim hash = BCryptor.HashPassword(tbPass) ' to do: Try/Catch for an email that already exists Using dbCon As New MySqlConnection(MySQLConnStr), cmd As New MySqlCommand(sql, dbCon) cmd.Parameters.Add("@email", MySqlDbType.Text).Value = tbEmail cmd.Parameters.Add("@n", MySqlDbType.Text).Value = tbUserName cmd.Parameters.Add("@pw", MySqlDbType.Text).Value = hash dbCon.Open() cmd.ExecuteNonQuery() End Using
Dim bRet As Boolean = False ' login user Dim sql = "SELECT pwhash FROM userlogin WHERE email = @email" Using dbCon As New MySqlConnection(MySQLConnStr), cmd As New MySqlCommand(sql, dbCon) ' data for the where clause cmd.Parameters.Add("@email", MySqlDbType.Text).Value = tbEmail dbCon.Open() Using rdr = cmd.ExecuteReader() ' read from the reader to load data If rdr.Read() Then ' get the saved hash Dim savedHash = rdr.GetString(0) bRet = BCryptor.Verify(tbPass, savedHash) Else bRet = False End If End Using ' return whether the hash verified Return ret End Using
Disposewhich means they may very well allocate resources which need to be released. The code uses each of them in a
Usingblock. This creates them at the start and disposes of them at the end of the Block.
The random salt originally generated when the account was created becomes part of the hash (as well as the work factor you used) as shown here:
Dim pw = "My!Weak#Pa$$word" Dim salt = BCryptor.GenerateSalt(12) Dim hash = BCryptor.HashPassword(pw, salt) Console.WriteLine(salt) Console.WriteLine(hash)
"$2a$" is the work factor.