Fuera en la naturaleza tenemos una tabla de usuarios. Una tabla de usuarios suele ser
ID | username | salt | encrypted_password | horridly_insecure_reset_key
===========================================================================
1 | user1 | foo | 09b6d39aa22fcb8698687e1af09a3af9 | NULL
2 | user2 | bar | 6c07c60f4b02c644ea1037575eb40005 | NULL
3 | user3 | baz | 09b6d39aa22fcb8698687e1af09a3af9 | reset
Entonces, un método de autenticación tendrá un aspecto parecido a
def authenticate(user, password)
u = User.find(user: user)
return u.encrypted_password == encrypt(password + u.salt)
end
Al tener un salt por usuario, garantiza que incluso si se conoce la contraseña para user1 no se puede averiguar la contraseña para user2 o user3 sin su salt.
También te aseguras de no poder descifrar el salt al tener un conjunto de contraseñas cifradas y probar algunas contraseñas cifradas.
En esencia, de esta manera, cada ataque contra un usuario debe iniciarse desde cero.
Incluso si un atacante tiene una lista de usuarios y sales, todavía necesita hacer el cracking contra todos y cada uno de los usuarios para ver si tienen una coincidencia de contraseña. Si tuviera un grupo de sales, o un sal estático, podría saber que la contraseña del usuario1 es la contraseña y luego encontrar todas las contraseñas cifradas que coincidan. De esta manera, al menos, los retrasa un poco más.
Ahora, cuando observamos las sales, queremos reducir la reutilización de la sal. Dos sales idénticas facilitarán a los atacantes. Si dos personas comparten la misma sal y la misma contraseña, romper un usuario romperá el otro.
Digamos que solo usamos estas tres sales. Y tenemos 3000 usuarios. Eso significa que 1000 personas tienen la misma sal. Si el 1% de ellos tiene una contraseña de "contraseña", esas personas pueden ser descifradas al mismo tiempo. 10 cuentas son hackeadas a la vez. Porque conocemos las tres sales. Es un tramo muy fácil para que 30 personas sean atacadas a la vez.
Ahora si cada sal es única. Y sabemos que la contraseña del usuario1 es la contraseña, que no le sirve de nada. Aún tienes solo 1 usuario crackeado. Aún tiene que hacer "do password + salt = contraseña encriptada" para todos los otros 2999 usuarios.
Una nota muy importante.
La seguridad a través de la oscuridad no es seguridad. Eso no significa que debas publicar tu tabla de usuarios en google porque es una tontería. Pero al medir la seguridad, debes asumir que el atacante tiene todo. No puede decir: "Pero ellos no sabrán la aplicación porque no tienen el código fuente". Porque ellos podrían. No significa regalar tus sales, solo significa que no es una verdadera seguridad. Suponga que tienen el nombre de usuario y el nombre salt, y luego intente dificultarles la obtención de la contraseña.
SUPER IMPORTANTE NOTA
El código y la tabla utilizados aquí son aproximadamente 9,000 veces demasiado simples para un uso real. Las contraseñas no están encriptadas, las sales son demasiado cortas, el método es un poco simplista, en resumen, hacer algo como esto en la producción no es algo que deba considerarse seguro. Escogí estas causas simples para el punto de demostración, no porque sean seguras.