好的,我之前发过这个问题,但只得到了我要求的答案的一半。简单地说,我有一个应用程序,它使用存储在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 & "'"
我知道这是一个很简单的问题,但是我需要人们了解我解决这个问题的方法。任何帮助将不胜感激。
答案 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注入受到攻击的方法 - 一旦您了解它的详细信息,您就能看到陷阱......
要考虑的另一个功能是登录失败“窗口” - 一个滑动时间段,在该时间段内,在该帐户被锁定(可能是暂时的)之前允许一定数量的失败登录。这意味着暴力破解密码变得不切实际。这通常是通过针对用户帐户记录FailedLoginAttempts
和FailedLoginTimeout
来处理的。如果登录失败,请将超时设置为现在+ 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()