¿Puedo descartar una clave privada y usar la clave pública como una función hash?

0

Sí, sí, lo sé "no inventes tus propios protocolos a menos que seas un experto". No es necesario que me grites, solo quiero saber si hay una falla en esta idea y si no, alguien la ha hecho antes.

La motivación aquí es que quiero poder autenticar a los usuarios. Sé que la solución estándar es saltear y hash contraseñas. Pero no me gusta el hecho de que la propia contraseña debe enviarse al servidor para verificarla. ¿Qué pasa si alguien escucha? El lado del cliente puede cifrar y enviar la contraseña, pero tampoco me gusta porque quizás mi clave de descifrado tenga pérdidas y alguien que haya registrado el tráfico web anterior pueda deducir todas las contraseñas. La autenticación no es un problema nuevo, por lo que no voy a insistir más en las ventajas y desventajas de las soluciones habituales.

Mi idea

Para cada usuario (a) el servidor almacena una clave pública (g ^ x_a) y la contraseña cifrada con esa clave pública (g ^ {x_a} * p_a). La clave privada asociada se destruyó rápidamente o (mejor aún, nunca se calculó). El generador de grupo g se mantiene para la generación de claves futuras. La relación habitual se aplica g ^ a * g ^ b = g ^ {a + b}. El proceso de autenticación es el siguiente

  1. El usuario Alice solicita la autenticación

  2. El servidor Bob genera una nueva clave pública temporal g ^ t (de nuevo sin una clave privada asociada). Bob multiplica esta clave pública temporal en sus datos de Alicia. Esto da como resultado g ^ t * g ^ {x_a} = g ^ {t + x_a} = g ^ {x_a} 'y g ^ t * g ^ {x_a} * p_a = g ^ {t + x_a} * p_a = g ^ {x_a} '* p_a. Bob se deshace de la clave pública temporal, dejándolo solo con una nueva clave pública (g ^ {x_a} ') y la contraseña de Alice cifrada con esta clave. Él le envía la nueva llave a Alicia.

  3. Alice toma la clave dada por Bob y la usa para cifrar su contraseña. Ella le envía el valor cifrado a Bob.

  4. Bob autentica a Alice si el valor dado coincide con los datos cifrados calculados en el paso 2.

Para recapitular

  1. En ningún momento el servidor (o un pirata informático de la base de datos) puede descifrar la contraseña. Una vez que las claves privadas han desaparecido, el cifrado de la clave pública funciona efectivamente como un hash.

  2. Dado que cada usuario está encriptado con una clave diferente, las contraseñas son efectivamente saladas. Una mesa de arco iris no funcionaría aquí.

  3. Un pirata informático con una imagen anterior de la base de datos no puede deducir valores futuros de g ^ x_a * p_a escuchando el tráfico web, ya que eso requeriría deducir la clave temporal (lo que requiere resolver un registro discreto). Por lo tanto, una imagen de base de datos filtrada no permite que un atacante suplante a los usuarios.

  4. Ni el servidor ni el cliente tienen claves privadas para administrar. Solo el cliente necesita mantener la información secreta y la información secreta puede ser legible para los humanos.

  5. (inconveniente) un atacante tiene una pequeña ventana de tiempo entre los pasos 2 y 4 donde puede penetrar en el servidor y hacerse pasar por un usuario utilizando los datos que encontró.

pregunta IIAOPSW 20.07.2018 - 09:29
fuente

2 respuestas

3

Un problema muy "fácil" sobre (cualquier) transporte cifrado de contraseñas:

  • Enviándolo en texto sin formato a través de HTTP, por supuesto, cualquier sniffer puede leerlo y usarlo para iniciar sesión.
  • El envío de texto sin formato a través de HTTPS (donde todos los datos están encriptados, no solo la contraseña sola) ya está bien.
  • El envío de una contraseña encriptada dentro de HTTPS no ofrece ningún beneficio.
  • Y contraseñas encriptadas a través de HTTP (y el servidor espera que estén encriptadas): sigue teniendo el problema de que un sniffer puede leer la contraseña encriptada, enviarla al servidor por sí mismo e iniciar sesión correctamente.

Entonces, dime, ¿por qué estás cifrando las contraseñas durante la transferencia?

Sobre su combinación de claves públicas, con RSA-OAEP, etc., esto simplemente no funcionará (si nunca ha oído hablar de OAEP, debería saber que RSA no es seguro).

Hay otros problemas, pero estos dos solos ya hacen que tu esquema sea inútil.

    
respondido por el deviantfan 20.07.2018 - 12:42
fuente
1

@deviantfan da una buena respuesta; Quiero expandir.

Una idea interesante y puede funcionar (después de un análisis cuidadoso por parte de personas más criptógrafas que yo), pero ¿por qué no usar simplemente una función hash regular con sal? Por un lado, RSA es lento . Realmente lento. (para cualquier mensaje de más de aproximadamente 256 bits, es más eficiente cifrar en RSA una clave AES y luego cifrar el mensaje en AES).

Curiosamente, la gente no parece publicar tiempos de referencia para RSA keygen, pero parece que la creación de una nueva clave RSA temporal toma aproximadamente 1 segundo para RSA 2048, y aproximadamente 20 segundos para RSA 4096. Eso es un montón de carga en El servidor y la latencia al usuario.

Como señala @Ben, lento es bueno para las funciones hash de almacenamiento de contraseñas, pero no este lento . Además, con el hash de contraseña lento, el servidor debe realizar la operación de hash lento una vez por inicio de sesión legítimo, mientras que el atacante debe hacerlo por conjetura, reduciendo su número de conjeturas por segundo. Aquí, el servidor debe hacer el keygen lento una vez por cada inicio de sesión legítimo, pero el atacante nunca tiene que hacerlo porque obtiene la clave pública y luego puede adivinarla. En realidad, está inclinando la cantidad de trabajo en el servidor frente a la cantidad de trabajo que el atacante debe hacer sustancialmente a favor del atacante.

    
respondido por el Mike Ounsworth 20.07.2018 - 15:56
fuente

Lea otras preguntas en las etiquetas