¿Hash lento sin sal?

1

Estoy tratando de diseñar un esquema de seguridad que involucre un secreto compartido pero no es una situación de contraseña de cuenta tradicional. El servidor almacenaría un conjunto de "claves", cada una de las cuales tiene un blob de datos asociado. Para que cualquiera pueda acceder a los datos de una clave determinada, todo lo que necesitan saber es el nombre de texto simple de la clave. Entonces, si Alice crea datos usando "piña" como la clave, Bob puede pedirle al servidor los datos para la clave "piña" y el servidor devolverá los datos.

Es completamente intencional que Bob pueda compartir la palabra secreta con otras personas, o que las personas adivinen al azar "piña" y obtengan los datos accidentalmente. Solo quiero evitar que alguien sea capaz de usar bruta forzando fácilmente un gran número de claves para palabras comunes del diccionario. Me gustaría que ninguno de los datos de texto simple se envíe al servidor, de modo que las personas que ejecutan el servidor no puedan espiar los datos del usuario ni saber cuáles son las claves de texto simple. E idealmente, si el servidor estuviera comprometido, llevaría mucho tiempo forzar bruscamente cada una de las claves de texto sin formato y / o descifrar los datos correspondientes.

Mi idea de cómo podría funcionar esto es que si Alice quiere crear nuevos datos, su cliente toma la "piña" clave y ejecuta un algoritmo hash muy lento, creando el código hash correspondiente para la piña. Luego, su cliente encripta el paquete de datos con "piña" y también utiliza algún tipo de método de encriptación que es difícil de forzar. Alice enviaría ambos al servidor, que verificará que el hash no exista, y luego almacenará el hash / par de datos. Más tarde, Bob podría repetir el mismo proceso de creación de un código hash para la piña, luego pedirle al servidor los datos para ese hash y finalmente descifrar los datos devueltos utilizando la piña como la clave. El proceso de creación del hash inicial sería lento, pero tanto Alice como Bob podrían almacenarlo localmente en su cliente, por lo que solo habría que hacerlo una vez por clave.

¿Hay alguna forma mejor de hacer esto? ¿Hay algoritmos de hash lentos que no impliquen el uso de sal, lo que evitaría que Alice y Bob descubran el mismo código hash seguro sin comunicarse entre sí? ¿Hay alguna forma de utilizar un archivo sal, pero sigue utilizando este método general en el que el servidor nunca ve ningún texto sin formato? ¿Hay problemas de seguridad con este tipo de esquema que no estoy considerando?

    
pregunta Chris Graham 18.09.2018 - 18:40
fuente

1 respuesta

3

Funciones de derivación de claves

Lo que estás describiendo no es realmente diferente de las funciones de derivación de claves (KDF) ya utilizadas en muchos cifrados / contraseñas contextos hash. Muchos KDF tienen un parámetro configurable cost que puede permitirle aumentar o disminuir el "Tiempo de CPU" total (estoy simplificando) necesario para generar la clave real a partir de la contraseña. En este caso, lo que usted llama key (es decir, "piña") sería efectivamente una contraseña que se ejecuta a través de un KDF para generar una clave citrográfica, que luego se utiliza para el cifrado / descifrado de los datos. Nunca tendría que enviar la contraseña al servidor, solo la clave generada, que siempre se crea utilizando el KDF en el lado del cliente.

Factores de costo

El último bit (que genera el lado del cliente clave) sería importante, porque de lo que estás hablando, el factor de costo debería ser muy alto. Eso podría ser un detalle que te falta. La única forma de permitir que las personas compartan una contraseña e incluso que adivinen contraseñas, pero que no sea capaz de forzar de manera efectiva las contraseñas aleatorias, es si el KDF es muy lento. Normalmente, el parámetro de costo se ajusta de modo que el tiempo para generar la clave en el hardware "bueno" sea, por ejemplo, de 0,2 segundos (estoy simplificando y omitiendo muchos detalles por ejemplo). La razón por la que elige una escala de tiempo como ~ 0.2 segundos para la generación de claves es para equilibrar el deseo de hacer costosa la fuerza bruta, pero también para que su sistema pueda realizar las operaciones necesarias en la escala de tiempo que los usuarios están dispuestos a esperar (es decir, nadie quiere esperar 30 segundos cada vez que inician sesión).

El problema

Sin embargo, incluso si un atacante solo puede marcar una "contraseña" por segundo, aún quedan 86400 segundos en un día, lo que significa que puede pasar por todo el diccionario de inglés de Oxford (~ 170,000 palabras) en solo unos días. . Como resultado, para evitar que alguien pueda usar palabras comunes de diccionario con fuerza bruta, está hablando de un proceso de generación de claves que debería tomar al menos unos minutos, y dudo que eso detenga a un atacante dedicado (especialmente si tienen hardware de gama alta que puede ejecutar el KDF en menos tiempo). Sin embargo, si lo hace, eso significa que sus usuarios legítimos también tendrán que esperar esos mismos minutos antes de que puedan obtener resultados de su sistema. Después de todo, no hay manera de diferenciar entre un usuario legítimo de su sistema y un atacante, por lo que la única manera de frenar a los atacantes es reducir la velocidad de todos . Entonces, para hacer lo que quiere hacer, tendrá que reducir la velocidad de su KDF para que se tarde un poco de tiempo en ejecutarse, pero es muy posible que el nivel de "lentitud" que necesita para asegurar el nivel que usted necesita. el deseo (es decir, detener la fuerza bruta de las palabras comunes del diccionario) será tan lento que sus usuarios no están dispuestos a esperar a que su sistema haga su trabajo. En última instancia, encontrar ese equilibrio entre la facilidad de uso y la seguridad dependerá de usted y sus usuarios.

Una posible solución

Puede solucionar algunos de los problemas utilizando la regulación del lado del servidor en lugar de hacer un factor de costo arbitrariamente grande. Imagine que las llamadas a la API donde el usuario dice "proporcionarme datos para esta clave" no devuelven resultados de inmediato, sino que generan una solicitud en cola que solo responde después de X período de tiempo. Esto le permitiría bloquear la fuerza bruta independientemente del nivel de hardware al que tenga acceso el atacante, no ralentizaría su servidor con un largo proceso de KDF y tampoco penalizaría a los usuarios con hardware lento. La desventaja, por supuesto, es que se trata de un control del lado del servidor, por lo que si su base de datos pierde, un pirata informático podría ir a la ciudad a fuerza bruta a la velocidad de su hardware.

    
respondido por el Conor Mancone 18.09.2018 - 19:11
fuente

Lea otras preguntas en las etiquetas