BCrypt Проверить сохраненный хэш пароля
Сохранение хешированного пароля в базе данных прошло успешно. Но при проверке, хранится ли входной пароль и хеш в базе данных, он всегда возвращает 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)
With sqlLogin
.Parameters.AddWithValue("@userid", txt_username.Text)
.Parameters.AddWithValue("@userpass", hash)
End With
Dim Reader As MySqlDataReader = sqlLogin.ExecuteReader()
If (BCrypt.Net.BCrypt.Verify(pw, hash)) Then
MessageBox.Show("Login Succesful!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Information)
Me.Hide()
Reader.Close()
ElseIf Reader.HasRows = False Then
MessageBox.Show("Invalid Login Information!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
txt_username.Text = ""
txt_password.Text = ""
txt_username.Focus())
End If
1 ответ
Особенно, когда речь идет о шифровании, вы должны иметь общее представление о принципах и концепциях. Соленое хеширование паролей объясняет типичные ошибки и дает ряд рекомендаций (один BCrypt
так что вы можете быть на правильном пути).
Похоже, вы не читаете сохраненный хэш из БД, прежде чем проверять. Вы не показываете, как оно сохраняется, но это важно для его проверки.
' 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
Заметки
DbConnection
,DbCommand
а такжеDbDataReader
все реализоватьDispose
Это означает, что они могут очень хорошо распределять ресурсы, которые должны быть освобождены. Код использует каждый из них вUsing
блок. Это создает их в начале и избавляется от них в конце блока.- Это использует электронную почту для уникального идентификатора, потому что там много Стивов. Это означает, что SQL вернет максимум одну запись.
- После загрузки хешированного pw из БД используйте его для проверки введенной попытки ввода пароля. Ваш код, кажется, создает новый хэш (и фактически ничего не загружает из БД).
Случайная соль, изначально созданная при создании учетной записи, становится частью хэша (а также используемого вами рабочего фактора), как показано здесь:
Dim pw = "My!Weak#Pa$$word"
Dim salt = BCryptor.GenerateSalt(12)
Dim hash = BCryptor.HashPassword(pw, salt)
Console.WriteLine(salt)
Console.WriteLine(hash)
Выход:
$ 2a $ 12 $ XPC20niJIhZPxaKvJkSUfO
$ 2a $ 12 $ XPC20niJIhZPxaKvJkSUfO / rwIetoScCze.tOcVS / aJzowvjpCPlq
12
после "$2a$"
это фактор работы.