Безопасно хранить имена пользователей и пароли в базе данных?
У меня есть люди, которые вводят имя пользователя и пароль для этого в клане, и мне нужно знать, безопасно ли использовать этот код, чтобы отправить его в базу данных или если он даже безопасен в базе данных.
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()
Я использую Parameters, чтобы избежать SQL-инъекций.
————————————————– ——————————–
- Удаленный сервер возвратил неожиданный ответ: (413) Request Entity Too Large.
- URL-адрес кликов в окне сообщений Winform?
- Несогласованность в поведении по принципу «один за другим» между разными типами значений
- Имя не существует в ошибке пространства имен в XAML
- Узел выбора XPath с пространством имен
Это не дубликат, так как это было другим способом запросить и сохранить пароль. Он использовал MD5 для hashирования пароля.
- Задание логического значения для целого числа возвращает -1 для true?
- перебирать все текстовые поля в форме, в том числе внутри группового windows
- VB.NET 'With' Statement - обнимать или избегать?
- VB.NET. Какова цель classа или модуля?
- Что обычно лучше всего использовать - StringComparison.OrdinalIgnoreCase или StringComparison.InvariantCultureIgnoreCase?
- Как получить размер удобочитаемого файла в аббревиатуре байтов с помощью .NET?
- Опция Strict по умолчанию в VB.NET
- У XSLT есть функция Split ()?
Процесс хранения паролей с базовым показателем безопасности довольно прост:
- Хешируйте пароли с солью
- Используйте различную соль для каждого пользователя / пароля
- Храните соль с хешированным паролем в БД
- Когда они пытаются войти в систему, запустите попытку PW через один и тот же метод; сравните результат.
Если они введут правильный пароль, хешированные PW будут совпадать. Хеширование защищает пользователей от атак, а также дворника, идущего по экрану с отображаемой таблицей members
.
Создание соли и Хеширование 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 и соль как часть записи пользователя. Соль не секретна, но меняйте ее, когда / если пользователь меняет свой пароль.
Сравнение попытки входа в систему
' 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, это должно привести к тому же хешу, это так просто. Код хеширования не так уж и сложный:
Хэш-методы
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
) в качестве соли, но просто не так сложно использовать криптографический генератор случайных чисел. - Как и с hashированным паролем, возвращаемая строка больше из-за кодировки.
- Создавайте новую соль каждый раз, когда пользователь меняет свой пароль. Не используйте глобальную соль, она побеждает цель.
- Вы также можете hash PW несколько раз. Часть ключа состоит в том, чтобы потребовать много времени, чтобы попробовать все различные комбинации, если / при атаке.
- Функции являются идеальными кандидатами для членов classа
Shared
/static
.
Заметим также, что статья, связанная с Кеннетом, стоит прочитать.
Обратите внимание, что в статье упоминается, что 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
Вам нужны обе части: после того, как вы сделали попытку войти в PW, сравните ее с split(1)
.
Нет, вы не должны хранить текстовый пароль в своей базе данных.
Причина в том, что если ваша firebase database взломана / украдена / скомпрометирована, все ваши пароли пользователя доступны хакеру.
Вместо этого вы должны сделать следующее: – Когда пользователь подписывается, сохраните его имя пользователя в базе данных вместе с hashированной версией пароля. Когда пользователь попытается войти в систему, получите имя пользователя из базы данных, хеш-пароль предоставил и сравнил его с хешированным паролем в базе данных.
Хеширование – это способ преобразования строки в другую строку, где вы можете идти только в одну сторону (т. Е. Один и тот же ввод всегда будет генерировать один и тот же вывод, но вы никогда не сможете вернуть вход, если у вас есть только вывод).
Чтобы узнать, как хешировать строку, прочитайте следующую статью, у нее есть примеры кода для разных языков: https://crackstation.net/hashing-security.htm