在数据库中存储用户名和密码安全吗? [英] Is it safe to store usernames and passwords in the database?
问题描述
我让人们在氏族中提交用户名和密码,然后我需要知道使用此代码将其提交到数据库中是否安全,或者在数据库中甚至是安全的.
I have people submit a username and password for then in a clan and i need to know if it's safe to use this code to submit that into a database or if it's even safe in a database.
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注入攻击.
I use Parameters to avoid SQL Injection Attacks.
-------------------------------------------- --------------------------------------
这不是重复的,因为它以不同的方式询问和 存储密码.它使用MD5哈希密码.
This was not a duplicate as it was in a different way of asking and storing the password. It was using MD5 for hashing a password.
推荐答案
使用基本的安全措施存储密码的过程非常简单:
The process for storing passwords with a basic measure of security is fairly simple:
- 用salt散列密码
- 为每个用户/密码使用不同的盐
- 将带有哈希密码的盐存储在数据库中
- 当他们尝试登录时,请通过相同的方法运行尝试的PW.比较结果.
如果他们输入了正确的密码,则散列的PW将匹配.散列可以保护用户免受攻击,也可以保护看门人在显示members
表的屏幕上走动.
If they entered the correct password, the hashed PWs will match. Hashing protects the users from attacks as well as the janitor walking by a screen with the members
table on display.
' 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哈希和盐存储为用户记录的一部分.盐不是秘密,但是当用户更改密码时,可以更改盐.
Store the PW hash and the salt as part of the user's record. The salt is not secret, but change it when/if the user changes their password.
' 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
如果用户输入相同的PW,则应该产生相同的哈希,就这么简单.哈希码并不那么复杂:
If the user enters the same PW, it should result in the same hash, it is as simple as that. The hashing code is not all that complicated:
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
)之类的东西很诱人,但是使用密码随机数生成器并不难. - 与哈希密码一样,由于编码原因,返回字符串更长.
- 每次用户更改密码时创建一个新的盐.不要使用全局盐,它会达到目的.
- 您也可以多次对PW进行哈希处理.部分原因是,如果受到攻击,要花很长时间才能尝试所有各种组合.
- 该函数是
Shared
/static
类成员的理想候选者. - It is tempting to use something like a GUID (
System.Guid.NewGuid.ToString
) as the salt, but it just isn't all that hard to use the cryptographic random number generator. - As with the hashed password, the return string is longer due to the encoding.
- Create a new salt every time the user changes their password. Don't use a global salt, it defeats the purpose.
- You can also hash the PW multiple times. Part of the key is to make it take a long time to try all various combinations if/when attacked.
- The functions are ideal candidates for
Shared
/static
class members.
还请注意, Kenneth 链接的文章非常值得阅读.
Note also, the article linked to by Kenneth is well worth reading.
请注意,这篇文章提到了 The salt should be stored in the user account table alongside the hash
并不意味着您在数据库中必须有一个Salt
列.您可以在链接的文章中看到以下内容:
Note that the article mentions The salt should be stored in the user account table alongside the hash
This doesn't mean you must have a Salt
column in the DB. You can see the following being done in the linked article:
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
要从哈希密码中分离出盐,请执行以下操作:
To split the salt from the hashed password:
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
您需要两个部分:在对PW中的尝试登录进行哈希处理之后,将其与split(1)
进行比较.
You need both parts: after you hash the attempted log in PW, compare it to split(1)
.
这篇关于在数据库中存储用户名和密码安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!