El artículo de Coda Hale "Cómo almacenar una contraseña de forma segura" afirma que:
bcrypt tiene sales incorporadas para prevenir ataques de mesa arcoiris.
Cita este documento , que dice que en la implementación de OpenBSD de bcrypt
:
OpenBSD genera la sal bcrypt de 128 bits a partir de una secuencia de claves arcfour (arc4random (3)), sembrada con datos aleatorios que el núcleo recopila de los tiempos del dispositivo.
No entiendo cómo puede funcionar esto. En mi concepción de una sal:
- Debe ser diferente para cada contraseña almacenada, de modo que se deba generar una tabla de arcoíris separada para cada
- Debe almacenarse en algún lugar para que sea repetible: cuando un usuario intenta iniciar sesión, tomamos su intento de contraseña, repetimos el mismo procedimiento de sal y hash que hicimos cuando originalmente almacenamos su contraseña y comparamos
Cuando uso Devise (un administrador de inicio de sesión de Rails) con bcrypt, no hay una columna de sal en la base de datos, así que estoy confundido. Si la sal es aleatoria y no se almacena en ningún lado, ¿cómo podemos repetir de manera confiable el proceso de hash?
En resumen, ¿cómo puede bcrypt tener sales incorporadas ?
"OrpheanBeholderScryDoubt"
Creo que esa frase debería estar redactada de la siguiente manera:
La
bcrypt
utilidad en sí misma no parece mantener una lista de sales. Por el contrario, las sales se generan aleatoriamente y se agregan a la salida de la función para que se recuerden más adelante (de acuerdo con la implementación de Javabcrypt
). Dicho de otra manera, el "hash" generado porbcrypt
no es solo el hash. Más bien, es el hash y la sal concatenados.fuente
Bcrypt
agrega una sal aleatoria de "akd2! *", lo que resulta en "fooakd2! *", que se procesa y almacena. Más tarde, intento iniciar sesión con la contraseña "barra". Para ver si estoy en lo correcto, necesita hacer un hash "barakd2! *". Si la sal se generó al azar para comenzar, ¿cómo sabe cómo volver a agregarla a la "barra" antes de dividir y comparar?bcrypt
sabe cómo extraer la sal de la salida generada (que se almacena en la base de datos). Cuando llega el momento de autenticarse,bcrypt
separa la salida original en sus componentes hash y salt. El componente de sal se aplica a la contraseña entrante ingresada por el usuario.Para hacer las cosas aún más claras,
Dirección de registro / inicio de sesión ->
La contraseña + salt se cifra con una clave generada a partir de: cost, salt y la contraseña. llamamos a ese valor cifrado el
cipher text
. luego adjuntamos la sal a este valor y lo codificamos usando base64. adjuntando el costo y esta es la cadena producida a partir debcrypt
:$2a$COST$BASE64
Este valor se almacena eventualmente.
¿Qué necesitaría hacer el atacante para encontrar la contraseña? (otra dirección <-)
En caso de que el atacante tenga control sobre la base de datos, el atacante decodificará fácilmente el valor base64, y luego podrá ver la sal. La sal no es secreta. Aunque es al azar. Entonces tendrá que descifrar el
cipher text
.Lo que es más importante: no hay hashing en este proceso, sino cifrado costoso de la CPU: descifrado. así, las tablas de arcoíris son menos relevantes aquí.
fuente
Esto es de la documentación de la interfaz PasswordEncoder de Spring Security,
Lo que significa que uno tendrá que hacer coincidir la Contraseña sin procesar que el usuario ingresará nuevamente en el próximo inicio de sesión y la hará coincidir con la contraseña codificada de Bcrypt que se almacena en la base de datos durante el inicio de sesión / registro anterior.
fuente