sql >> Base de Datos >  >> RDS >> Mysql

¿Es seguro almacenar nombres de usuario y contraseñas en la base de datos?

El proceso para almacenar contraseñas con una medida básica de seguridad es bastante simple:

  • Hash las contraseñas con sal
  • Utilice un salt diferente para cada usuario/contraseña
  • Almacene la sal con la contraseña cifrada en la base de datos
  • Cuando intenten iniciar sesión, ejecute lo que intentó PW a través del mismo método; comparar el resultado.

Si ingresaron la contraseña correcta, los PW cifrados coincidirán. Hashing protege a los usuarios de los ataques, así como al conserje que pasa por una pantalla con los members mesa en exhibición.

Creación de sal y hash del 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=="

Almacene el hash PW y la sal como parte del registro del usuario. La sal no es secreta, pero cámbiela cuando/si el usuario cambia su contraseña.

Comparación de un intento de inicio de sesión

' 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 el usuario ingresa el mismo PW, debería dar como resultado el mismo hash, es tan simple como eso. El código hash no es tan complicado:

Métodos hash

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 tentador usar algo como un GUID (System.Guid.NewGuid.ToString ) como la sal, pero no es tan difícil usar el generador criptográfico de números aleatorios.
  • Al igual que con la contraseña cifrada, la cadena de retorno es más larga debido a la codificación.
  • Crea un salt nuevo cada vez que el usuario cambia su contraseña. No use una sal global, anula el propósito.
  • También puede codificar el PW varias veces. Parte de la clave es hacer que tome mucho tiempo probar todas las combinaciones si/cuando es atacado.
  • Las funciones son candidatas ideales para Shared / static miembros de la clase.

Tenga en cuenta también, el artículo vinculado por Kenneth vale la pena leerlo.

Tenga en cuenta que el artículo menciona The salt should be stored in the user account table alongside the hash Esto no significa que debas tener un Salt columna en la base de datos. Puede ver lo siguiente en el artículo vinculado:

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

Para dividir la sal de la contraseña cifrada:

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

Necesita ambas partes:después de codificar el intento de inicio de sesión de PW, compárelo con split(1) .