VB Application Search MySQL Database for Login Credentials

时间:2014-01-17 22:41:25

标签: mysql sql sql-server vb.net

好的,我之前发过这个问题,但只得到了我要求的答案的一半。简单地说,我有一个应用程序,它使用存储在My SQL数据库中的登录凭据来检查登录凭据。我听到的一个尴尬的问题是,我以最适合我的方式创建它,并且以一种对我来说很容易理解的方式 - 我对编程和自学没有经验。我使用的方法 - 虽然容易出现'注入攻击'和其他类似的危险,但适用于我的应用程序,我的应用程序显然有安全性(CD-Key检查和密码。)

所以,实际细节:

连接成功建立,我可以操作应用程序中的数据。

连接代码:

Public Sub conecDB()
    'This is called upon program start.
    Dim connectionString As String = SQLLoginIn.serveriptxt.Text    'This is the server IP/Server name.  If server is intalled on your local machine, your IP should be 127.0.0.1 or you may use localhost
    Dim strDbase As String = SQLLoginIn.databasenametxt.Text  'Database name
    Dim strUser As String = SQLLoginIn.databaseusertxt.Text    'Database user
    Dim strPass As String = "CENSORED"     'Database password

    If connDB.State <> ConnectionState.Open Then connDB.ConnectionString = "Data Source=" & connectionString.Trim & ";Initial Catalog=" & strDbase.Trim & ";MultipleActiveResultSets=False;User ID=" & strUser.Trim & ";Password=" & strPass
    If connDB.State <> ConnectionState.Open Then connDB.Open()
End Sub

这非常有效,因为我需要它。

我将(单独的表格)的记录添加到我的程序中的列表视图lvRec

代码:

Public Sub dispRec(ByVal PstrSQL As String)
        'This is called once the connection is established.
        frmMain.lvRec.Items.Clear()

    With comDB
        .CommandText = PstrSQL
        rdDB = .ExecuteReader
    End With
    Do While rdDB.Read
        Item = frmMain.lvRec.Items.Add(rdDB!Members_ID.ToString)
        Item.SubItems.Add(rdDB!Gamer_Tag.ToString.Trim)
        'And a bunch of more
        Item.SubItems.Add(rdDB!Games_Owned.ToString.Trim)
        My.Application.DoEvents()
    Loop
    rdDB.Close()
End Sub

所以现在你已经看到我如何使用SQL你可能会尖叫“这不是你怎么做的!”,但正如我所说,它适用于我:)问题发生在我想要的时候使用自己的用户名和用户对用户进行变换。密码存储在名为Logins的其他表中。

我知道我需要/可以使用以下代码在Logins表中使用登录凭据查询用户输入,但我不知道如何返回任何可用的功能,如布尔值结果或类似的东西。我只是想知道用户输入的凭证是否正确,因此现有的TRUE是很好的。

SQL查询:

SQL = "Select * from logins " & _
  "where Name like '%" & Me.Usernametxt.Text.Trim & _
  "%' AND Passkey LIKE '" & Me.Passwordtxt.Text.Trim  & "'"

我知道这是一个很简单的问题,但是我需要人们了解我解决这个问题的方法。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

不是答案,而是帮助您以更健壮的方式开始身份验证......

[请注意,你应该从不]作为福音,因为我们所有人都会犯错误,安全是一个非常困难的话题,即使对于专业人士来说也是如此......] < / p>

您要遵循的过程类似于以下(在伪代码中)

UserRecords = ExecuteSql("SELECT UserID, PasswordHash, Salt, IsEnabled FROM Users WHERE Username = '<Blah>'")

If UserRecords.Count <> 1
    'Login Failed
End If

Dim UserRecord = UserRecords.First

If Hash(PasswordEnteredByUser & UserRecord.Salt) <> UserRecord.PasswordHash
    'Login Failed
End If

If UserRecord.IsEnabled <> True
    'Login Failed
End If

' Login was successful, continue as planned

散列函数通过输入例如MyPassword!并将其转换为其他内容(例如AB0653AAAF330)来工作。把它想象成一个香肠制造商 - 你把猪放在一端,然后从另一端拿出一根香肠。将香肠变回猪是不可能的。然而,理论上,将同一只猪放入两次会产生相同的香肠。通过存储香肠而不是猪的数据库违规won't reveal users passwords

当您的数据库被破坏时,“Salt”会出现。想象一下,两个用户选择了相同的密码。你知道bob的密码是MyPassword!,你可以看到它存储为AB0653AAAF330。密码哈希值为AB0653AAAF330的其他任何人都使用相同的密码 - 这意味着可能会同时破坏多个帐户。

另一方面,如果有一个用户特定的随机字符串并附加到其密码预先散列,则Bob的密码被视为MyPassword!AAAAAAAAA,其中(比方说)哈希值为099DEF3333445和Jane的(相同)密码被视为MyPassword!BBBBBBBBB,其中(比方说)哈希值为AAAAE1234400

简而言之,知道Bob的密码不会告诉你Jane有同样的密码。

这仍然是一个非常不完整的例子。还有许多其他的事情需要考虑(例如散列算法.MD5散列被认为是弱的,bcrypt有意计算成本太高,使暴力破坏更加困难等)但希望它会给你一个粗略的想法让你开始。

您还希望进行身份验证二进制 - 成功或失败。如果您告诉用户“该用户名无效”(而不是简单的“登录失败”)作为帮助,他们可以使用该功能通过重复确定有效的用户名。

我全心全意地建议您阅读this article有关公司如何通过SQL注入受到攻击的方法 - 一旦您了解它的详细信息,您就能看到陷阱......

要考虑的另一个功能是登录失败“窗口” - 一个滑动时间段,在该时间段内,在该帐户被锁定(可能是暂时的)之前允许一定数量的失败登录。这意味着暴力破解密码变得不切实际。这通常是通过针对用户帐户记录FailedLoginAttemptsFailedLoginTimeout来处理的。如果登录失败,请将超时设置为现在+ 30分钟。如果尝试&gt;某个阈值和超时未到期,锁定帐户。如果登录失败,请延长超时。你明白了。

最后,如果你真的安全意识,当用户成功登录时,告诉他们上次登录的时间。如果某人已经度假一周并看到“你的上次登录是昨天“他们立即知道出了什么问题。

一切顺利。

答案 1 :(得分:0)

关于如何从SQL命令返回单个结果的常规命令:

Dim sqlConnection1 As New SqlConnection("Your Connection String")
Dim cmd As New SqlCommand
Dim success As Object

cmd.CommandText = "SELECT COUNT(*) FROM logins " & _
                  "WHERE Name = @Name " & _
                  "AND Passkey = @Passkey"
cmd.Parameters.AddWithValue("@Name",Me.Usernametxt.Text.Trim)
cmd.Parameters.AddWithValue("@Passkey",Me.Passwordtxt.Text.Trim)

cmd.CommandType = CommandType.Text
cmd.Connection = sqlConnection1

sqlConnection1.Open()

success = cmd.ExecuteScalar()

sqlConnection1.Close()