用户名和密码验证vb.net

用户名和密码验证vb.net,vb.net,basic,Vb.net,Basic,下面的程序检查用户名和密码是否在数据库中(用visual basic编写并使用Access数据库)。然而,当我在不同的情况下输入用户名或密码时,该程序仍然有效。例如,如果我的数据库的用户名为“john”,密码为“johnpassword”,那么我的程序接受用户名为“john”,密码为“johnpassword” 如何解决这个问题 Dim con As New OleDbConnection("Provider=Microsoft.jet.oledb.4.0;data source=C:\User

下面的程序检查用户名和密码是否在数据库中(用visual basic编写并使用Access数据库)。然而,当我在不同的情况下输入用户名或密码时,该程序仍然有效。例如,如果我的数据库的用户名为“john”,密码为“johnpassword”,那么我的程序接受用户名为“john”,密码为“johnpassword”

如何解决这个问题

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

如果改为使用密码哈希,则可以解决两个问题:

  • 不应将密码存储为纯文本
  • 散列将使密码区分大小写
适用于创建散列;您还需要在数据库中为每个用户存储一个随机生成的salt

有许多网站,例如,解释为什么盐渍和散列是可取的

您仍然需要决定是否需要用户名区分大小写

编辑

这似乎是(即)进行区分大小写比较的一种方法,因此您只需从数据库中获取用户名并在程序中进行检查,如下所示:

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

当然,当用户注册时,您仍然需要创建代码以将适当的数据放入数据库。

SQL大小写不敏感的可能重复是一个非常常见的恼人的错误,请检查上面的问题,看看这是否有帮助如果密码为:'或1=1,则不考虑软件的“不重要”程度,你应该养成认真对待任何密码的习惯,这样当你开始编写更“重要”的软件时,你就已经记下了。TODO:在数据库中创建大小合适的二进制字段-我不确定你在这里的意思。你能告诉我吗?-@andrewmorton@SUNILsalt和hash是字节数组,因此可以在数据库中选择合适的列来存储它们。字符串列类型是不够的,它需要是二进制的。