Mysql
 sql >> Base de données >  >> RDS >> Mysql

Est-il sûr de stocker les noms d'utilisateur et les mots de passe dans la base de données ?

Le processus de stockage des mots de passe avec une mesure de sécurité de base est assez simple :

  • Hachez les mots de passe avec du sel
  • Utilisez un salt différent pour chaque utilisateur/mot de passe
  • Stocker le sel avec le mot de passe haché dans la base de données
  • Lorsqu'ils essaient de se connecter, exécutez ce que le PW a tenté par la même méthode ; comparer le résultat.

S'ils ont entré le mot de passe correct, les mots de passe hachés correspondront. Le hachage protège les utilisateurs des attaques ainsi que le concierge passant devant un écran avec les members tableau affiché.

Créer du sel et hacher le 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=="

Stockez le hachage PW et le sel dans le dossier de l'utilisateur. Le sel n'est pas secret, mais changez-le quand/si l'utilisateur change son mot de passe.

Comparer une tentative de connexion

' 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

Si l'utilisateur entre le même mot de passe, cela devrait entraîner le même hachage, c'est aussi simple que cela. Le code de hachage n'est pas si compliqué :

Méthodes de hachage

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
  • Il est tentant d'utiliser quelque chose comme un GUID (System.Guid.NewGuid.ToString ) comme le sel, mais il n'est tout simplement pas si difficile d'utiliser le générateur de nombres aléatoires cryptographiques.
  • Comme pour le mot de passe haché, la chaîne de retour est plus longue en raison de l'encodage.
  • Créer un nouveau sel chaque fois que l'utilisateur modifie son mot de passe. N'utilisez pas de sel global, cela va à l'encontre de l'objectif.
  • Vous pouvez également hacher le PW plusieurs fois. Une partie de la clé est de faire en sorte qu'il faille beaucoup de temps pour essayer toutes les différentes combinaisons en cas d'attaque.
  • Les fonctions sont des candidats idéaux pour Shared / static membres de la classe.

Notez également l'article lié à par Kenneth vaut la peine d'être lu.

Notez que l'article mentionne The salt should be stored in the user account table alongside the hash Cela ne signifie pas que vous devez avoir un Salt colonne dans la BD. Vous pouvez voir ce qui suit en cours dans l'article lié :

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

Pour séparer le sel du mot de passe haché :

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

Vous avez besoin des deux parties :après avoir haché la tentative de connexion PW, comparez-la à split(1) .