La necesidad de esconder la sal para un hachís

99

En el trabajo tenemos dos teorías en competencia sobre las sales. Los productos en los que trabajo usan algo como un nombre de usuario o un número de teléfono para agregar sal al hash. Esencialmente algo que es diferente para cada usuario pero que está disponible para nosotros. El otro producto genera aleatoriamente una sal para cada usuario y cambia cada vez que el usuario cambia la contraseña. Luego, la sal se cifra en la base de datos.

Mi pregunta es si el segundo enfoque es realmente necesario. Puedo entender desde una perspectiva puramente teórica que es más seguro que el primer enfoque, pero ¿qué pasa desde un punto de vista práctico? En este momento, para autenticar a un usuario, la sal debe estar desencriptada y aplicada a la información de inicio de sesión.

Después de pensarlo, simplemente no veo una ganancia de seguridad real de este enfoque. Cambiar la sal de una cuenta a otra, todavía hace que sea extremadamente difícil para alguien intentar forzar el algoritmo hash, incluso si el atacante sabía cómo determinar rápidamente qué era para cada cuenta. Esto se basa en la suposición de que las contraseñas son lo suficientemente seguras. (Obviamente, encontrar el hash correcto para un conjunto de contraseñas donde todas son de dos dígitos es significativamente más fácil que encontrar el hash correcto de las contraseñas que son de 8 dígitos). ¿Soy incorrecto en mi lógica o hay algo que me falta?

EDITAR: Bien, aquí está la razón por la que creo que es realmente discutible cifrar la sal. (déjame saber si estoy en el camino correcto).

Para la siguiente explicación, asumiremos que las contraseñas son siempre de 8 caracteres y la sal es 5 y que todas las contraseñas están compuestas por letras minúsculas (solo facilita las matemáticas).

Tener una sal diferente para cada entrada significa que no puedo usar la misma tabla de arco iris (de hecho, técnicamente podría hacerlo si tuviera una de tamaño suficiente, pero ignorémoslo por el momento). Esta es la verdadera clave de la sal por lo que entiendo, porque para romper todas las cuentas tengo que reinventar la rueda, por así decirlo, para cada una. Ahora, si sé cómo aplicar la sal correcta a una contraseña para generar el hash, lo haría porque una sal realmente solo extiende la longitud / complejidad de la frase hash. Así que estaría recortando el número de combinaciones posibles que necesitaría generar para "saber" que tengo la contraseña + sal de 13 ^ 26 a 8 ^ 26 porque sé qué es la sal. Ahora eso lo hace más fácil, pero sigue siendo realmente difícil.

Entonces, encriptar la sal. Si sé que la sal está cifrada, no intentaría descifrarla (suponiendo que sepa que tiene un nivel suficiente de cifrado) primero. Lo ignoraría. En lugar de tratar de descubrir cómo descifrarlo, volviendo al ejemplo anterior, solo generaría una tabla de arco iris más grande que contenga todas las claves para 13 ^ 26. Sin saber que la sal definitivamente me ralentizaría, pero no creo que agregue la monumental tarea de intentar descifrar el cifrado de la sal primero. Por eso no creo que valga la pena. Pensamientos

Aquí hay un enlace que describe cuánto tiempo se mantendrán las contraseñas bajo un ataque de fuerza bruta: http://www.lockdown.co.uk/?pg=combi

kemiller2002
fuente
Buena pregunta, Kevin, muy oportuna. No puedo comentar sobre la seguridad, pero hay un impacto en el rendimiento de todo este cifrado y descifrado, seguro.
DOK
No necesita ignorar la tabla de arco iris de tamaño decente; esa tabla también hace que la sal encriptada sea discutible, ya que puede descifrar el hash salado y volver a usarse para descifrar el hash original. La buena noticia es que la creación de la mesa probablemente llevaría siglos.
tloach
Lo que me llama la atención es que no estoy totalmente seguro de que una tabla de arcoíris de ese tamaño tarde tanto en crearse. Es una idea loca, tomar una plataforma de computación distribuida como Kraken (realmente eso es lo que es) para generarla. ¿Cuánto tiempo tomaría entonces?
kemiller2002
3
@Kevin: SHA1 devuelve una cadena hexadecimal de 40 caracteres, por lo que hay 40 ^ 16 posibles valores de retorno. Suponiendo que una sola computadora puede calcular 1000 hashes cada segundo, calculo que 1000 000 computadoras tomarían alrededor de 10 mil millones de años para generar una tabla de arco iris capaz de determinar una cadena de ese tamaño.
tloach
+1 buena pregunta y estás bien leído. Creo que tienes una respuesta incorrecta a esta pregunta. Siempre debe ser un secreto porque el hash no se puede romper hasta que se obtiene. Debería leer sobre CWE-760 ( cwe.mitre.org/data/definitions/760.html )
torre

Respuestas:

45

La respuesta aquí es preguntarse ¿de qué está realmente tratando de protegerse? Si alguien tiene acceso a su base de datos, entonces tiene acceso a las sales cifradas y probablemente también tenga acceso a su código. Con todo eso, ¿podrían descifrar las sales cifradas? Si es así, el cifrado es bastante inútil de todos modos. La sal realmente está ahí para hacerlo, por lo que no es posible formar una tabla de arco iris para descifrar toda la base de datos de contraseñas de una sola vez si se rompe. Desde ese punto de vista, siempre que cada sal sea única, no hay diferencia, se requeriría un ataque de fuerza bruta con sus sales o las sales cifradas para cada contraseña individualmente.

tloach
fuente
Algo nuevo en estos conceptos. Por lo tanto, puede parecer una pregunta ingenua, pero ¿no sería más fácil formar esa tabla de arcoíris conociendo la sal para cada contraseña, ya que probaría solo una combinación para el valor de la sal para cada contraseña posible?
stdout
La tabla de arco de, por ejemplo, 1000 contraseñas de uso común, rompería esto casi a la misma velocidad que el hash. La única forma en que esto funcionaría es si asume que la distribución de sus contraseñas es uniforme ... y sabemos que no lo son
DaWNFoRCe
100

Ocultar una sal es innecesario.

Se debe usar una sal diferente para cada picadillo. En la práctica, esto es fácil de lograr al obtener 8 o más bytes del generador de números aleatorios de calidad criptográfica.

De una respuesta mía anterior :

Salt ayuda a frustrar los ataques de diccionario precalculados.

Suponga que un atacante tiene una lista de posibles contraseñas. Puede usar el hash de cada uno y compararlo con el hash de la contraseña de su víctima y ver si coincide. Si la lista es grande, esto podría llevar mucho tiempo. No quiere dedicar tanto tiempo a su próximo objetivo, por lo que registra el resultado en un "diccionario" donde un hash apunta a su entrada correspondiente. Si la lista de contraseñas es muy, muy larga, puede usar técnicas como una Mesa Arcoíris para ahorrar espacio.

Sin embargo, supongamos que su próximo objetivo sacó su contraseña. Incluso si el atacante sabe qué es la sal, su tabla precalculada no tiene valor: la sal cambia el hash resultante de cada contraseña. Tiene que volver a codificar todas las contraseñas de su lista, colocando la sal del objetivo en la entrada. Cada sal diferente requiere un diccionario diferente, y si se usan suficientes sales, el atacante no tendrá espacio para almacenar diccionarios para todos. El comercio de espacio para ahorrar tiempo ya no es una opción; el atacante debe recurrir al hash de cada contraseña de su lista para cada objetivo que quiera atacar.

Entonces, no es necesario mantener la sal en secreto. Asegurarse de que el atacante no tenga un diccionario precalculado correspondiente a esa sal en particular es suficiente.


Después de pensar un poco más en esto, me di cuenta de que engañarse pensando que la sal se puede esconder es peligroso. Es mucho mejor asumir que la sal no se puede ocultar y diseñar el sistema para que sea seguro a pesar de eso. Proporciono una explicación más detallada en otra respuesta.


Sin embargo, recomendaciones recientes del NIST fomentan el uso de una "sal" secreta adicional (he visto a otros llamar a esta "pimienta" secreta adicional). Se puede realizar una iteración adicional de la derivación de clave utilizando este secreto como sal. En lugar de aumentar la fuerza contra un ataque de búsqueda precalculado, esta ronda protege contra la adivinación de contraseñas, al igual que la gran cantidad de iteraciones en una buena función de derivación de claves. Este secreto no sirve para nada si se almacena con la contraseña hash; debe gestionarse como un secreto, y eso podría ser difícil en una gran base de datos de usuarios.

erickson
fuente
1
Es necesario esconder la sal porque el hachís no se puede romper hasta obtenerlo. Esto está relacionado con CWE-760 ( cwe.mitre.org/data/definitions/760.html )
torre
28
@The Rook - No, estás malinterpretando ese tema. Se refiere al uso de sales predecibles. No dice nada sobre mantener la sal en secreto. De hecho, no puedes guardar el secreto de la sal sin usar otro secreto ... en cuyo caso, ¿por qué no usarías el segundo secreto como la sal? Usar el nombre de usuario como una sal es malo porque es probable que varios sistemas compartan el mismo nombre de usuario, por lo que vale la pena construir una tabla para esa sal en particular. Las sales al azar son las mejores, pero no es necesario mantenerlas en secreto.
erickson
1
@erickson, creo que estás mezclando terminología aquí. Las sales no frustran los ataques de diccionario a menos que estén ocultas. Muchas sales se almacenan abiertamente. Y si conoces la sal, tu ataque de diccionario solo se ralentiza por el tiempo que lleva agregar la sal a tu término de diccionario :) Las sales previenen las búsquedas en la tabla Rainbow ... que son bastante rápidas. Si el atacante conoce su sal, no está protegido de un ataque de diccionario. Sin embargo, si el atacante no conoce tu sal, estás protegido de un ataque de diccionario y debe usar un ataque de fuerza bruta.
Ultratrunks
4
@Ultratrunks Sí, he aclarado algunas de mis respuestas sobre este tema, utilizando el término "ataques de diccionario precalculados". Más general que las tablas Rainbow, se refiere a cualquier estructura que permita una búsqueda inversa de un texto plano usando su hash como clave. Independientemente de los términos que elija, my explica explícitamente que la sal está destinada a vencer las tablas Rainbow y mecanismos similares. Siempre debes asumir que el atacante conoce la sal. Si fuera posible mantenerlo en secreto, no necesitaría codificar la contraseña.
erickson
3

Mi comprensión de la "sal" es que dificulta el descifrado, pero no intenta ocultar los datos adicionales. Si está tratando de obtener más seguridad haciendo que la sal sea "secreta", entonces realmente solo quiere más bits en sus claves de cifrado.

gbarry
fuente
3

El segundo enfoque es solo un poco más seguro. Las sales protegen a los usuarios de los ataques de diccionario y de las tablas de arco iris. Hacen que sea más difícil para un atacante ambicioso poner en peligro todo su sistema, pero siguen siendo vulnerables a los ataques que se centran en un usuario de su sistema. Si usa información que está disponible públicamente, como un número de teléfono, y el atacante se da cuenta de esto , entonces le ha salvado un paso en su ataque. Por supuesto, la pregunta es discutible si el atacante obtiene toda su base de datos, sales y todo.

EDITAR: Después de volver a leer esta respuesta y algunos de los comentarios, se me ocurre que parte de la confusión puede deberse al hecho de que solo estoy comparando los dos casos muy específicos presentados en la pregunta: sal aleatoria vs. sal no aleatoria. La cuestión de utilizar un número de teléfono como sal es discutible si el atacante obtiene toda su base de datos, no la cuestión de utilizar una sal en absoluto.

Bill el lagarto
fuente
¿Cómo se protegen contra los ataques de diccionario?
tloach
Obligando al atacante a crear un nuevo diccionario para cada combinación de contraseña + sal. Sin sal, se puede usar un diccionario con toda la tabla de contraseñas.
Bill the Lizard
"Por supuesto, la pregunta es discutible si el atacante obtiene toda su base de datos, sales y todo". ¿No es por eso que la sal está encriptada?
Patrick McElhaney
1
@Bill: Acabas de describir una mesa de arcoíris. Un ataque de diccionario es cuando tomo palabras normales e intento autenticarme con ellas. Es una fuerza bruta con un espacio de respuesta muy reducido. Ningún hash defiende contra la fuerza bruta.
tloach
Nunca he oído hablar de esta práctica, pero no soy un experto en seguridad. Parece que cifrar sales únicas agregaría una capa adicional de protección contra los ataques de la tabla de arco iris.
Bill the Lizard
3

... algo como un nombre de usuario o un número de teléfono para agregar sal al hash. ...

Mi pregunta es si el segundo enfoque es realmente necesario. Puedo entender desde una perspectiva puramente teórica que es más seguro que el primer enfoque, pero ¿qué pasa desde un punto de vista práctico?

Desde un punto de vista práctico, una sal es un detalle de implementación. Si alguna vez cambia la forma en que se recopila o mantiene la información del usuario, y tanto los nombres de usuario como los números de teléfono a veces cambian, para usar sus ejemplos exactos, es posible que haya comprometido su seguridad. ¿Quiere que un cambio tan externo tenga preocupaciones de seguridad mucho más profundas?

¿Detener el requisito de que cada cuenta tenga un número de teléfono debe implicar una revisión de seguridad completa para asegurarse de que no haya abierto esas cuentas a un compromiso de seguridad?

Luego
fuente
2
Sin mencionar si está utilizando un poco de información de usuario arbitraria, cuando cambian esa información, necesita que ingresen su contraseña nuevamente para que pueda encriptarla nuevamente con la nueva sal.
Treborbob
3

Una sal escondida ya no es sal. Es pimienta. Tiene su uso. Es diferente a la sal.

Pepper es una clave secreta agregada a la contraseña + sal que convierte el hash en un HMAC (Código de autenticación de mensajes basado en hash). Un pirata informático con acceso a la salida de hash y la sal puede, teóricamente, adivinar por fuerza bruta una entrada que generará el hash (y, por lo tanto, pasará la validación en el cuadro de texto de la contraseña). Al agregar pimienta, aumenta el espacio del problema de una manera criptográficamente aleatoria, lo que hace que el problema sea intratable sin hardware serio.

Para obtener más información sobre la pimienta, consulte aquí .

Consulte también hmac .

John Wu
fuente
2

Aquí hay un ejemplo simple que muestra por qué es malo tener la misma sal para cada picadillo

Considere la siguiente tabla

UserId  UserName,   Password
     1  Fred       Hash1 =  Sha(Salt1+Password1)    
     2  Ted        Hash2 =  Sha(Salt2+Password2)    

Caso 1 cuando salt 1 es lo mismo que salt2 Si Hash2 se reemplaza con Hash1, el usuario 2 podría iniciar sesión con la contraseña del usuario 1

Caso 2 cuando salt 1 no es el mismo salt2 Si Hash2 se reemplaza con Hash1, entonces el usuario2 no puede iniciar sesión con la contraseña del usuario 1.

Charles Faiga
fuente
No estamos usando el mismo hash para cada cuenta, estamos usando el mismo tipo de información para cada hash. Por ejemplo, la sal de una cuenta es el número de teléfono de la cuenta, etc.
kemiller2002
Sé que esto es mucho tiempo después, pero ... no puedes confiar en las sales para protegerte contra este tipo de ataque. Debemos asumir que un atacante sabe todo sobre el sistema de autenticación que no sea el secreto (es decir, la contraseña). Por lo tanto, debemos suponer que el atacante sabe a) lo que estamos usando como sal (la mayoría de las veces esto se almacena en la misma base de datos y tabla en texto plano) yb) cómo estamos haciendo hash con el salt (es decir, agregando, hash dos veces, etc). Si el usuario tiene la capacidad de cambiar los hash, debemos asumir que también puede cambiar la sal. Las sales no ayudarán aquí.
Dave Satch
1

Hay dos técnicas, con diferentes objetivos:

  • La "sal" se utiliza para hacer que dos contraseñas iguales se cifren de forma diferente. De esta manera, un intruso no puede usar de manera eficiente un ataque de diccionario contra una lista completa de contraseñas encriptadas.

  • El "secreto" (compartido) se agrega antes de aplicar un hash a un mensaje, de modo que un intruso no pueda crear sus propios mensajes y aceptarlos.

Javier
fuente
0

Tiendo a esconder la sal. Utilizo 10 bits de sal anteponiendo un número aleatorio del 1 al 1024 al principio de la contraseña antes de aplicar el hash. Al comparar la contraseña que ingresó el usuario con el hash, hago un ciclo de 1 a 1024 y pruebo todos los valores posibles de sal hasta encontrar la coincidencia. Esto toma menos de 1/10 de segundo. Tuve la idea de hacerlo de esta manera desde PHP password_hash y password_verify . En mi ejemplo, el "costo" es 10 por 10 trozos de sal. O por lo que dijo otro usuario, la "sal" oculta se llama "pimienta". La sal no está cifrada en la base de datos. Es un bruto forzado a salir. Haría que la tabla del arco iris sea necesaria para invertir el hash 1000 veces más grande. Utilizo sha256 porque es rápido, pero aún se considera seguro.

Russell Hankins
fuente
Entonces, si mi contraseña es "345678" y la sal aleatoria que antepone es, digamos, "12". Si alguien ingresa "45678" como mi contraseña. Esto parece incorrecto en muchos sentidos.
Yurippenet
-1

Realmente, depende del tipo de ataque que intente proteger sus datos.

El propósito de un salt único para cada contraseña es evitar un ataque de diccionario contra toda la base de datos de contraseñas.

Cifrar la sal única para cada contraseña haría más difícil descifrar una contraseña individual, sí, pero debe sopesar si realmente hay un gran beneficio. Si el atacante, por fuerza bruta, encuentra que esta cadena:

Marianne2ae85fb5d

hashes a un hash almacenado en la base de datos, ¿es realmente tan difícil averiguar qué parte es el pase y cuál es la sal?

Lucas Omán
fuente
2
Si alguien hace una fuerza bruta con una contraseña tan imposible de adivinar, diría que de todos modos está perdido, porque aparentemente tienen tecnología en la que nadie ha pensado todavía.
Instance Hunter