Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Ist es sicher, Benutzernamen und Passwörter in der Datenbank zu speichern?

Der Vorgang zum Speichern von Passwörtern mit einem grundlegenden Maß an Sicherheit ist ziemlich einfach:

  • Hashen Sie die Passwörter mit Salt
  • Verwenden Sie für jeden Benutzer/jedes Passwort ein anderes Salt
  • Speichern Sie das Salt mit dem gehashten Passwort in der DB
  • Wenn sie versuchen, sich anzumelden, führen Sie das versuchte PW durch dieselbe Methode aus; Vergleichen Sie das Ergebnis.

Wenn sie das richtige Passwort eingegeben haben, stimmen die gehashten PWs überein. Hashing schützt die Benutzer vor Angriffen sowie den Hausmeister, der mit den members an einem Bildschirm vorbeigeht Tisch ausgestellt.

Erstellen von Salt und Hashen des PW

Die Salt-Größe von
' 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=="

Speichern Sie den PW-Hash und das Salt als Teil des Benutzerdatensatzes. Das Salt ist nicht geheim, aber ändern Sie es, wenn/falls der Benutzer sein Passwort ändert.

Vergleich eines Anmeldeversuchs

' 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

Wenn der Benutzer dasselbe PW eingibt, sollte es denselben Hash ergeben, so einfach ist das. Der Hashing-Code ist gar nicht so kompliziert:

Hash-Methoden

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
  • Es ist verlockend, so etwas wie eine GUID zu verwenden (System.Guid.NewGuid.ToString ) als Salz, aber es ist einfach nicht so schwer, den kryptografischen Zufallszahlengenerator zu verwenden.
  • Wie beim gehashten Passwort ist der Rückgabestring aufgrund der Kodierung länger.
  • Jedes Mal, wenn der Benutzer sein Passwort ändert, ein neues Salt erstellen. Verwenden Sie kein globales Salz, es verfehlt den Zweck.
  • Sie können das PW auch mehrfach hashen. Ein Teil des Schlüssels besteht darin, dafür zu sorgen, dass es lange dauert, alle verschiedenen Kombinationen auszuprobieren, falls/wenn sie angegriffen werden.
  • Die Funktionen sind ideale Kandidaten für Shared / static Klassenmitglieder.

Beachten Sie auch den Artikel, auf den Kenneth verweist ist sehr lesenswert.

Beachten Sie, dass der Artikel erwähnt The salt should be stored in the user account table alongside the hash Das bedeutet nicht, dass Sie ein Salt haben müssen Spalte in der DB. In dem verlinkten Artikel können Sie sehen, dass Folgendes getan wird:

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

So trennen Sie das Salt vom gehashten Passwort:

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

Sie benötigen beide Teile:Nachdem Sie das versuchte Protokoll in PW gehasht haben, vergleichen Sie es mit split(1) .