将用户名和密码存储在数据库中是否安全?

我有人提交用户名和密码,然后在一个部落,我需要知道是否安全使用此代码提交到数据库中,或者它甚至是安全的数据库。

MySQLCon.Open() Dim SQLADD As String = "INSERT INTO members(username,password) VALUES(@memberToAdd, @memberPassword)" COMMAND = New MySqlCommand(SQLADD, MySQLCon) COMMAND.Parameters.AddWithValue("@memberToAdd", memberToAdd.Text) COMMAND.Parameters.AddWithValue("@memberPassword", membersPassword.Text) COMMAND.ExecuteNonQuery() MySQLCon.Close() MySQLCon.Dispose() 

我使用参数来避免SQL注入攻击。

————————————————– ——————————–

这不是重复的,因为它以不同的方式询问和存储密码。 它使用MD5来散列密码。

用基本的安全措施存储密码的过程相当简单:

  • 用盐散列密码
  • 为每个用户/密码使用不同的盐
  • 将哈希密码的salt存储在数据库中
  • 当他们尝试login时,通过相同的方法运行尝试的PW; 比较结果。

如果他们input正确的密码,散列的PW将匹配。 散列保护用户免受攻击以及pipe理员走在显示members表的屏幕上。

创build盐和散列PW

 ' salt size is 32 (0-31 Private Const SaltSize As Integer = 31 ... Dim dbPW As String = TextBox1.Text Dim dbSalt = CreateNewSalt(SaltSize) ' eg: "dsEGWpJpwfAOvdRZyUo9rA==" Dim SaltedPWHash As String = GetSaltedHash(dbPW, dbSalt) ' examples: ' using SHA256: bbKN8wYYgoZmNaG3IsQ2DPS2ZPIOnenl6i5NwUmrGmo= ' using SHA512: ' 0vqZWBIbOlyzL25l9iWk51CxxJTiEM6QUZEH1ph+/aNp+lk4Yf8NYv8RLhYtbqCNpOqO3y8BmM+0YWtbAhE+RA==" 

存储PW散列和salt作为用户logging的一部分。 盐不是秘密的,但如果用户更改密码,则更改密码。

比较login尝试

 ' check if PW entered equals DB Dim pwTry = TextBox2.Text ' hash the login attempt using the salt stored in the DB Dim pwLogin = GetSaltedHash(pwTry, dbSalt) ' compare the hash of what they entered to whats in the DB: If String.Compare(SaltedPWHash, pwLogin, False) = 0 Then ' okay! Console.Beep() End If 

如果用户input相同的密码,它应该导致相同的散列,就像那样简单。 哈希代码并不是那么复杂:

散列方法

 Private Function GetSaltedHash(pw As String, salt As String) As String Dim tmp As String = pw & salt ' or SHA512Managed Using hash As HashAlgorithm = New SHA256Managed() ' convert pw+salt to bytes: Dim saltyPW = Encoding.UTF8.GetBytes(tmp) ' hash the pw+salt bytes: Dim hBytes = hash.ComputeHash(saltyPW) ' return a B64 string so it can be saved as text Return Convert.ToBase64String(hBytes) End Using End Function Private Function CreateNewSalt(size As Integer) As String ' use the crypto random number generator to create ' a new random salt Using rng As New RNGCryptoServiceProvider ' dont allow very small salt Dim data(If(size < 7, 7, size)) As Byte ' fill the array rng.GetBytes(data) ' convert to B64 for saving as text Return Convert.ToBase64String(data) End Using End Function 
  • 使用GUID( System.Guid.NewGuid.ToString )作为盐是很诱人的,但使用密码随机数生成器并不难。
  • 与散列密码一样,返回string由于编码而更长。
  • 每次用户更改密码时都会创build一个新的salt。 不要使用全球性的食盐,它会破坏目的。
  • 您也可以多次散列PW。 部分关键在于如果受到攻击时要花费很长时间来尝试各种组合。
  • 这些函数是Shared / static类成员的理想候选者。

还请注意, Kenneth所撰写的文章非常值得一读。


请注意, 文章提到The salt should be stored in the user account table alongside the hash这并不意味着你必须在数据库中有一个Salt列。 您可以在链接的文章中看到以下内容:

 Dim dbPW As String = TextBox1.Text Dim dbSalt = CreateNewSalt(SaltSize) ' get the salted PW hash Dim SaltedPWHash As String = GetSaltedHash(dbPW, dbSalt) ' store salt with the hash: SaltedPWHash = String.Format("{0}:{1}", dbSalt, dbPW) ' salt + ":" + hashed PW now ready to store in the db 

从哈希密码中分离盐:

 Dim SaltAndPWHash = rdr.Item("PWHash").ToString() Dim split = SaltAndPWHash.Split(":"c) ' split on ":" Dim Salt = split(0) ' element(0) == salt Dim StoredPWHash = split(1) ' element(1) == hashed PW 

你需要这两个部分:在散列试图loginPW后,将其与split(1)进行比较。

不,你不应该在数据库中存储明文密码。

原因是,如果您的数据库被黑客入侵/被盗/入侵,您的所有用户密码都可供黑客使用。

你应该做什么,而不是如下: – 当用户注册时,将他的用户名保存在数据库中,连同密码的散列版本 – 当用户尝试login时,从数据库中获取用户名,散列密码提供并将其与数据库中的散列密码进行比较。

散列是将string转换为不同string的一种方式,在这种情况下,您只能使用一种方法(即,相同的input始终会生成相同的输出,但如果只有输出,则永远不会获得input)。

要了解如何对一个string进行散列,请阅读以下文章,其中包含不同语言的代码示例: https : //crackstation.net/hashing-security.htm