用户名和密码验证 vb.net
username and password verification vb.net
我下面的程序检查用户名和密码是否在数据库中(用 visual basic 编写并使用 Access 数据库)。但是,该程序可以工作,当我在不同的情况下输入用户名或密码时,它仍然可以工作。例如,如果我的数据库有用户名 "john" 和密码 "johnspassword",我的程序接受用户名 "JOHN" 和密码 "JOHNSPASSWORD".
我该如何解决这个问题?
Dim con As New OleDbConnection("Provider=Microsoft.jet.oledb.4.0;data source=C:\Users\jacob\Desktop\MS Office\project.mdb")
Dim cmd As OleDbCommand = New OleDbCommand("SELECT * FROM tblUsers WHERE UserID = '" & txtUserName_Field.Text & "' AND userPassword = '" & txtUserPassword_Field.Text & "' ", con)
con.Open()
Dim sdr As OleDbDataReader = cmd.ExecuteReader()
'If the record can be queried, it means passing verification, then open another form.
Dim empty =
Me.Controls.OfType(Of TextBox)().Where(Function(txt) txt.Text.Length = 0)
If empty.Any Then
MessageBox.Show(String.Format("Please fill in all the fields required"))
Else
If (sdr.Read() = True) Then
MessageBox.Show("The is valid!")
Form4.Show()
Me.Hide()
Else
MessageBox.Show("Invalid name or password!")
End If
End If
con.Close()
End Sub
如果您改用密码的哈希值,则可以解决两个问题:
- 您不应将密码存储为纯文本
- 哈希将使密码区分大小写
Rfc2898DeriveBytes Class适合创建散列;您还需要为每个用户在数据库中存储一个随机生成的盐。
有很多网站,例如 Salted Password Hashing - Doing it Right,解释了为什么需要加盐和散列。
您仍然需要决定是否需要用户名区分大小写。
编辑
似乎 Access doesn't have an efficient (i.e. sargable) 进行区分大小写比较的方式,因此您可以简单地从数据库中获取用户名并在您的程序中检查它,如下所示:
Option Infer On
Option Strict On
Imports System.Data.OleDb
Imports System.Security.Cryptography
Public Class SomeClass
'TODO: decide on the sizes for the salt and hash
'TODO: create binary fields in the database of appropriate sizes
'TODO: consider storing the number of iterations in the database
Const SALTLENGTH As Integer = 8
Const HASHLENGTH As Integer = 16
Const PBKDF2ITERATIONS As Integer = 20000
Friend Function PBKDF2Hash(password As String, salt As Byte(), iterations As Integer, hashSize As Integer) As Byte()
Dim hasher As New Rfc2898DeriveBytes(password, salt, iterations)
Return hasher.GetBytes(hashSize)
End Function
Function IsLoginValid(username As String, password As String) As Boolean
Dim salt(SALTLENGTH - 1) As Byte
Dim hashedPassword(HASHLENGTH - 1) As Byte
Dim usernameIsValid = False
Dim csb As New OleDbConnectionStringBuilder With {
.Provider = "Microsoft.jet.oledb.4.0",
.DataSource = "C:\Users\jacob\Desktop\MS Office\project.mdb"
}
Using conn As New OleDbConnection(csb.ConnectionString)
'TODO: use the actual column names
Using cmd As New OleDbCommand("SELECT UserID, salt, password FROM tblUsers WHERE UserID = ?", conn)
'TODO: use type of column as specified in the database
cmd.Parameters.Add(New OleDbParameter With {.OleDbType = OleDbType.VarWChar, .Value = username})
conn.Open()
Dim rdr = cmd.ExecuteReader()
If rdr.HasRows Then
rdr.Read()
If String.Compare(rdr.GetString(0), username, StringComparison.Ordinal) = 0 Then
rdr.GetBytes(1, 0, salt, 0, SALTLENGTH)
rdr.GetBytes(2, 0, hashedPassword, 0, HASHLENGTH)
usernameIsValid = True
End If
End If
conn.Close()
End Using
End Using
Dim expectedHash = PBKDF2Hash(password, salt, PBKDF2ITERATIONS, HASHLENGTH)
If usernameIsValid AndAlso hashedPassword.SequenceEqual(expectedHash) Then
Return True
End If
Return False
End Function
Private Sub bnLogin_Click(sender As Object, e As EventArgs) Handles bnLogin.Click
Dim username = txtUserName_Field.Text
Dim password = txtUserPassword_Field.Text
If username.Length = 0 OrElse password.Length = 0 Then
MessageBox.Show("Please fill in all the fields required.")
Exit Sub
End If
If IsLoginValid(username, password) Then
' user has supplied valid credentials
Else
MessageBox.Show("Invalid username or password.")
End If
End Sub
End Class
当然,当用户注册时,您仍然需要创建代码将适当的数据放入数据库。
我下面的程序检查用户名和密码是否在数据库中(用 visual basic 编写并使用 Access 数据库)。但是,该程序可以工作,当我在不同的情况下输入用户名或密码时,它仍然可以工作。例如,如果我的数据库有用户名 "john" 和密码 "johnspassword",我的程序接受用户名 "JOHN" 和密码 "JOHNSPASSWORD".
我该如何解决这个问题?
Dim con As New OleDbConnection("Provider=Microsoft.jet.oledb.4.0;data source=C:\Users\jacob\Desktop\MS Office\project.mdb")
Dim cmd As OleDbCommand = New OleDbCommand("SELECT * FROM tblUsers WHERE UserID = '" & txtUserName_Field.Text & "' AND userPassword = '" & txtUserPassword_Field.Text & "' ", con)
con.Open()
Dim sdr As OleDbDataReader = cmd.ExecuteReader()
'If the record can be queried, it means passing verification, then open another form.
Dim empty =
Me.Controls.OfType(Of TextBox)().Where(Function(txt) txt.Text.Length = 0)
If empty.Any Then
MessageBox.Show(String.Format("Please fill in all the fields required"))
Else
If (sdr.Read() = True) Then
MessageBox.Show("The is valid!")
Form4.Show()
Me.Hide()
Else
MessageBox.Show("Invalid name or password!")
End If
End If
con.Close()
End Sub
如果您改用密码的哈希值,则可以解决两个问题:
- 您不应将密码存储为纯文本
- 哈希将使密码区分大小写
Rfc2898DeriveBytes Class适合创建散列;您还需要为每个用户在数据库中存储一个随机生成的盐。
有很多网站,例如 Salted Password Hashing - Doing it Right,解释了为什么需要加盐和散列。
您仍然需要决定是否需要用户名区分大小写。
编辑
似乎 Access doesn't have an efficient (i.e. sargable) 进行区分大小写比较的方式,因此您可以简单地从数据库中获取用户名并在您的程序中检查它,如下所示:
Option Infer On
Option Strict On
Imports System.Data.OleDb
Imports System.Security.Cryptography
Public Class SomeClass
'TODO: decide on the sizes for the salt and hash
'TODO: create binary fields in the database of appropriate sizes
'TODO: consider storing the number of iterations in the database
Const SALTLENGTH As Integer = 8
Const HASHLENGTH As Integer = 16
Const PBKDF2ITERATIONS As Integer = 20000
Friend Function PBKDF2Hash(password As String, salt As Byte(), iterations As Integer, hashSize As Integer) As Byte()
Dim hasher As New Rfc2898DeriveBytes(password, salt, iterations)
Return hasher.GetBytes(hashSize)
End Function
Function IsLoginValid(username As String, password As String) As Boolean
Dim salt(SALTLENGTH - 1) As Byte
Dim hashedPassword(HASHLENGTH - 1) As Byte
Dim usernameIsValid = False
Dim csb As New OleDbConnectionStringBuilder With {
.Provider = "Microsoft.jet.oledb.4.0",
.DataSource = "C:\Users\jacob\Desktop\MS Office\project.mdb"
}
Using conn As New OleDbConnection(csb.ConnectionString)
'TODO: use the actual column names
Using cmd As New OleDbCommand("SELECT UserID, salt, password FROM tblUsers WHERE UserID = ?", conn)
'TODO: use type of column as specified in the database
cmd.Parameters.Add(New OleDbParameter With {.OleDbType = OleDbType.VarWChar, .Value = username})
conn.Open()
Dim rdr = cmd.ExecuteReader()
If rdr.HasRows Then
rdr.Read()
If String.Compare(rdr.GetString(0), username, StringComparison.Ordinal) = 0 Then
rdr.GetBytes(1, 0, salt, 0, SALTLENGTH)
rdr.GetBytes(2, 0, hashedPassword, 0, HASHLENGTH)
usernameIsValid = True
End If
End If
conn.Close()
End Using
End Using
Dim expectedHash = PBKDF2Hash(password, salt, PBKDF2ITERATIONS, HASHLENGTH)
If usernameIsValid AndAlso hashedPassword.SequenceEqual(expectedHash) Then
Return True
End If
Return False
End Function
Private Sub bnLogin_Click(sender As Object, e As EventArgs) Handles bnLogin.Click
Dim username = txtUserName_Field.Text
Dim password = txtUserPassword_Field.Text
If username.Length = 0 OrElse password.Length = 0 Then
MessageBox.Show("Please fill in all the fields required.")
Exit Sub
End If
If IsLoginValid(username, password) Then
' user has supplied valid credentials
Else
MessageBox.Show("Invalid username or password.")
End If
End Sub
End Class
当然,当用户注册时,您仍然需要创建代码将适当的数据放入数据库。