2014-01-17 45 views
1

好吧,我之前发布了这个问题,但只得到了我需要的一半答案。简单地说,我有一个应用程序,它将存储在My SQL数据库中的登录凭据进行检查。我听到的尴尬问题是,我已经以最适合自己的方式创建了它,并且以一种对我来说很简单的方式来理解 - 我没有经验过编程和自学。我使用的方法 - 虽然容易发生“注入式攻击”等这样的危险,是适合我的应用程序,显然还有安全在我的应用(CD-重点检查&密码。)VB应用程序搜索MySQL数据库的登录凭证

所以,实际的细节:

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

连接代码:

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 & "'" 

我知道这是这样一个简单的问题,很多的细节,但我需要的人了解我解决这个去的方式。任何帮助将非常感激。

+1

不要使用'LIKE',除非你真的需要模糊匹配 - 而且绝对不要使用密码 - 你知道输入密码'%'可以用于任何帐户,对吗?另外,虽然我明白你想要以“你的方式”来做,而且每个人都有自己的风格,但这不是做错事的借口。如果您不关心安全性,请彻底取消密码。如果你关心一点,这是不够的。 – Basic

+1

@Basic我回顾了我的做法并得出结论,这很糟糕。我现在正在学习和实施正确的方式;无论如何,这对我来说会更容易。感谢您指出'%'问题,我不知道这一点。 – user2980316

+1

我写了一些评论,指出你的方向是正确的,但决定一个非答案可能会更有帮助。见下文。 – Basic

回答

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() 
1

不是答案,而是帮助你开始以更稳健的方式认证...

[请记住,你应该从来没有采取一个SO的答案作为福音,因为我们所有人都犯错误和安全是一个非常困难的话题做甚至专业人士...]

这个过程你要遵循的是类似以下内容(伪)

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

当您的数据库被破坏时,“盐”进入播放。想象一下两个用户选择了相同的密码。你知道鲍勃的密码是MyPassword!,你可以看到它的存储为AB0653AAAF330。密码散列号为AB0653AAAF330的任何人都拥有相同的密码 - 这意味着多个帐户可能一次被破坏。

如果,在另一方面,有一个随机字符串,它是用户特定的,并且附加到他们的密码预先散列,Bob的口令被视为MyPassword!AAAAAAAAA其中(比方说)散列来099DEF3333445和Jane的(相同的)密码是视为MyPassword!BBBBBBBBB哪个(说)散列到AAAAE1234400

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

这仍然是一个可怕的不完整的例子。还有很多其他的事情需要考虑(例如散列算法,MD5哈希被认为是弱的,bcrypt的计算成本比较昂贵,因此使得暴力更加困难,等等),但是希望它能给你一个初步的想法。

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

我衷心建议你在一个公司是如何通过SQL注入妥协阅读this article - 一旦你知道它是如何工作的细节,你就可以看到的陷阱......

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

最后,如果你真的是安全意识,当用户成功登录时,告诉他们他们上次登录的时间。如果有人在假期待了一周并看到“您的上次登录是昨天”,他们立即知道某事是错的。

一切顺利。

相关问题