¿Esta solución de autenticación y encriptación es segura?

3

Necesito comunicarme a través de sockets TCP inseguros donde SSL / TLS no está disponible. ¿La siguiente solución proporciona un medio seguro de autenticación y cifrado?

-

  1. El cliente envía: nombre de usuario
  2. El servidor genera un token aleatorio (31 bytes).
  3. El servidor recupera una contraseña salt y hash (bcrypt) de la base de datos para el nombre de usuario dado.
  4. El servidor cifra el token aleatorio mediante el hash de contraseña.
  5. El cliente recibe: passwordSalt + encryptAes (token, passwordHash)
  6. El cliente obtiene el PasswordHash utilizando bcrypt en la contraseña y el salteado de la contraseña recibida.
  7. El cliente obtiene el token descifrando el token cifrado con el hash de la contraseña.
  8. El cliente genera una sal de "validación" aleatoria (15 bytes).
  9. El cliente genera un hash del token utilizando el sal de validación y lo cifra con el token.
  10. El cliente envía: encryptAes (validationSalt + md5 (token + validationSalt), token)
  11. El servidor obtiene el hash descifrando con el token.
  12. El servidor compara si el hash recibido es igual a md5 (token). Si son iguales, el cliente se ha autenticado.
  13. El servidor genera un hash del hash de contraseña utilizando el sal de validación, lo rellena con 15 bytes aleatorios y lo cifra con el token.
  14. El cliente recibe: encryptAes (randomBytes (15) + md5 (passwordHash + validationSalt), token)
  15. El cliente obtiene el hash al descifrarlo con el token.
  16. El cliente compara el hash con md5 (passwordHash + validationSalt). Si son iguales, el servidor se ha autenticado.

Todos los datos se cifrarán ahora con el token generado por el servidor.

-

El servidor está en Java, los clientes están en C ++ (UE4).

El cifrado de la clave pública no está disponible actualmente.

-

¿Hay algún defecto o debilidad en esta solución?

    
pregunta Zwarmapapa 14.03.2016 - 16:36
fuente

3 respuestas

3

Básicamente, creaste un esquema de autenticación secreto compartido aquí.

Sin embargo, no definió cuáles son sus objetivos de seguridad. Autenticación de entidad, autenticación de entidad fuerte, confidencialidad, anonimato, ...? Así que es difícil decir "(sí / no), esto es (no) seguro". Si sus objetivos de seguridad no son ninguno de los anteriores, es probable que esto sea seguro. ¡Pero yo no usaría esta cosa (espero que no te importe)! :-)

Parece que asumes que la clave de autenticación es la contraseña. Sin embargo, este no es el caso, ya que conocer el hash de la base de datos es suficiente para la autenticación exitosa. Pruébelo y juegue el cliente que solo conoce el hash de la contraseña y verá que funciona.

El problema aquí es que no especificaste exactamente cuál es el secreto. Sabiendo que puede hacer todo el proceso mucho más simple. Suponga que el secreto es el hash de la base de datos y desea autenticar al usuario en el servidor:

  • El servidor genera una clave de sesión y un número aleatorio, cifra ambos con el secreto y los envía al cliente
  • El cliente genera el secreto compartido al solicitar la contraseña
  • El cliente descifra la clave de sesión
  • El cliente agrega 1 al número aleatorio, lo cifra con la clave de sesión y lo envía de vuelta al servidor

Como puede ver, la seguridad aún depende de conocer el hash de la base de datos, pero la configuración de un secreto compartido y la autenticación del cliente se han vuelto mucho más sencillas. ¡Ten en cuenta que esto aún está lejos de ser seguro! Solo quería mostrar que las cosas a menudo no son lo que parecen. Jugar con las sales no hace que las cosas sean necesariamente mejores.

El punto es: Complicado no significa seguro, y, como se señaló anteriormente, no confíe en usted criptografía hecha por usted mismo ;-)

Editar : solo para el registro, piensa en oráculos, ataques de protocolo elegidos, ataques de reflexión, ... acostúmbrate a estas cosas e intenta encontrar ataques contra tu propio protocolo. Se divierte y aprenderás mucho.

    
respondido por el fr00tyl00p 14.03.2016 - 18:34
fuente
4

Su solución podría verse afectada por los siguientes conceptos:

Criptografía de bricolaje

DIY crypto es un anti-patrón de diseño de software seguro. La mayoría de los intentos (> 99%) fallarán. Sin embargo, respeto tu intento! :-) Por ejemplo: No revele la "contraseñaSalt", si no es necesario. Ayuda al atacante a romper el desafío. Después de una solicitud, un atacante conoce la sal y tiene un desafío que podría romperse. La seguridad se basa únicamente en una contraseña segura. El atacante puede descifrar la contraseña sin conexión. Este no debería ser el caso de los servicios en línea. Califico esto como altamente inseguro.

Perfect Forward Secrecy

La clave para el cifrado (token generado en el servidor) debe calcularse en ambos lados (cliente y servidor) usando Diffie-Hellman Key Exchange o similar. Si alguien registra el tráfico y obtiene la contraseña del usuario, podrá descifrar el token y luego descifrar todo el tráfico, posteriormente.

Pasos 13-16 no necesarios

Si el cliente puede descifrar "passwordSalt + encryptAes (token, passwordHash)" con éxito, el servidor debe conocer "passwordHash", por lo tanto, la contraseña del usuario.

Esta lista no está completa, ya que podrían estar presentes varias otras debilidades.

    
respondido por el honze 14.03.2016 - 17:13
fuente
1

Estás intentando recrear una rueda y, a menos que tengas conocimientos de criptografía, es probable que no sea una buena intención.

Su objetivo es enviar datos cifrados desde un servidor a un cliente con la limitación de que aún no puede existir una PKI. El problema es que estamos limitados a Symmetric Key, ¿no?

Hay dos enfoques aproximados que puede considerar:

Clave precompartida:

Las claves precargadas se generan y configuran en el cliente y el servidor y se usan como una clave común para el cifrado y descifrado. Su cifrado de datos se puede asegurar bastante bien de esta manera, pero se ocupa del mantenimiento de un PSK.

Función de derivación de claves: * Las Key Derivation Functions funcionan bajo un principio similar al de PSK, pero se generan en el cliente y el servidor al comienzo de una sesión. Los datos son datos compartidos entre los dos sistemas para generar un valor secreto que se puede usar para cifrar y descartar sistemas pt.

Tanto Java como C, C ++ tienen bibliotecas que pueden construir estas funciones.

    
respondido por el Shane Andrie 15.03.2016 - 18:37
fuente

Lea otras preguntas en las etiquetas