2017-12-08 25 views
1

私のプログラムでは、userNameとパスワードがデータベースに含まれているかどうか(Visual Basicで記述され、Accessデータベースを使用しているかどうか)を確認します。プログラムは動作しますが、別のケースでuserNameまたはpasswordを入力すると、それは引き続き動作します。たとえば、自分のデータベースのuserNameが "john"、パスワードが "johnspassword"の場合、私のプログラムはユーザー名を "JOHN"として、パスワードを "JOHNSPASSWORD"として受け入れます。ユーザー名とパスワードの確認vb.net

どのようにこの問題を解決しますか?

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 
+0

[WHERE句で大文字と小文字を区別する検索方法(SQL Serverを使用しています)](https://stackoverflow.com/questions/1831105/how-to-do-a-case- SQLの大文字と小文字を区別しないで検索する部分) –

+0

SQLの大文字と小文字の区別は非常によくある厄介なバグです。上記の質問を確認してください。 –

+3

パスワードが 'OR 1 = 1 –

答えて

3

あなたの代わりに、パスワードのハッシュを使用する場合、あなたは、あなたが持っている二つの問題解決:

  • をプレーンテキスト
  • ハッシュを作るだろうとあなたはパスワードを保存しないでくださいパスワードは大文字と小文字を区別する

Rfc2898DeriveBytes Classが適していますハッシュを作成する。各ユーザーのデータベースにランダムに生成された塩が保存されている必要があります。

多くのサイトがあります(例:Salted Password Hashing - Doing it Right)。なぜ塩析とハッシングが望ましいのか説明しています。

ユーザー名の大文字と小文字を区別する必要があるかどうかを判断する必要があります。

EDIT

それはあなたが単にデータベースからユーザー名を取得し、あなたのプログラムではこのような何かを、それを確認することができますので、大文字と小文字を区別して比較を行うことAccess doesn't have an efficient(すなわち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 

もちろん、ユーザー登録時に適切なデータをデータベースに格納するコードを作成する必要があります。

+1

"重要でない"ソフトウェアの作成方法にかかわらず、重要なソフトウェアの作成を開始する場合には、この方法が必要です。 –

+0

'TODO:適切なサイズのデータ​​ベースにバイナリフィールドを作成する - 私はあなたがここで何を意味するのかはっきりしていません。教えてください。 @andrewmorton – SUNIL

+0

@SUNIL塩とハッシュはバイトの配列なので、データベースに格納するのに適した列です。文字列型は十分ではなく、バイナリである必要があります。 –

関連する問題