Una forma segura de cifrar una conexión entre 2 clientes que protegen contra adversarios tanto pasivos como activos

4

Recientemente me interesé por el cifrado y los métodos detrás de ellos. Así que para un proyecto divertido / escolar, estoy creando un programa en Python para cifrar datos entre dos clientes (chat y archivos).

Realmente no estoy seguro de cómo hacer que sea realmente seguro contra ataques tanto pasivos como activos. En este momento, mi idea es usar un servidor para establecer un acuerdo entre los clientes de la siguiente manera:

  1. Una vez que un cliente se inicia, se conecta al servidor para que sepa que está vivo.
  2. El cliente bob le dice al servidor que quiere conectarse al cliente Alice
  3. El servidor envía un mensaje al cliente Alice que bob quiere configurar una conexión segura
  4. Alicia le dice al servidor que acepta la conexión
  5. El servidor genera un número aleatorio y lo cifra utilizando la clave pública del cliente El cliente tiene una clave RSA privada codificada (no cambia por conexión / cliente)
  6. El servidor envía el número aleatorio a Alice y Bob
  7. Alice y Bob descifran el número aleatorio y lo trocean, ambos lo envían de vuelta al servidor
  8. El servidor comprueba si ambos hashes son iguales (ninguno está atenuado)
  9. El servidor envía un OK o error a ambas partes
  10. Alice y Bob hacen el número de hash un número de veces igual al número aleatorio (por lo tanto, si el servidor envía 1234, lo hace de 1234 veces.
  11. Alice y Bob configuraron una clave común para esta conexión mediante el intercambio de claves Diffie-Hellman y cifran el intercambio con AES.
  12. Una vez que se decida una clave común, use esta clave o un hash de esta clave para el cifrado AES (esta clave cambia por conexión y todos los datos se envían a través de este canal)

El único problema que veo con este protocolo es si los adversarios pueden aplicar ingeniería inversa a mi código para obtener la clave privada, y pueden usar ataques activos tanto en la conexión de Alice como en la de Bob O si el servidor está comprometido.

Usaré py2exe para compilar el código, de esa manera debería ser difícil obtener la clave, pero no estoy seguro de cuán difícil sería.

Lo siento por la larga pregunta, pero se siente como una idea realmente horrible de codificar la clave en el cliente, pero no estoy seguro de a dónde ir desde aquí.

Reflexiones sobre esta idea / mejoras / ¿Cómo puedo hacerlo mejor?

Lo siento por cualquier error tipográfico, el inglés no es mi primer idioma.

    
pregunta Alfuananzo 18.12.2014 - 17:48
fuente

5 respuestas

1

No puede tener una clave privada codificada en el software que se distribuye.

Las dos opciones que veo son:

  1. Haga que cada cliente genere un par de claves único que usen para comunicarse con el servidor. Bob enviaría su clave pública al servidor cuando se conecte inicialmente. El servidor luego cifrará los mensajes a Bob con su clave pública. La primera comunicación entre el servidor y Alice será el servidor que le pedirá a Alice su clave pública para poder utilizarla en futuras comunicaciones. El servidor puede pasar una clave simétrica encriptada con sus claves públicas a cada uno de Bob y Alice para usar en futuras comunicaciones.
  2. Dale al servidor un par de claves. Cuando Bob se conecta por primera vez con el servidor, Bob crea una clave simétrica que cifra con la clave pública del servidor. El servidor y Bob usan esto para encriptar más comunicaciones. Cuando el servidor se pone en contacto por primera vez con Alice, le pasa su clave pública. Alice responde creando una clave simétrica y enviándola al servidor, cifrada con la clave pública del servidor. El servidor puede comunicarse con Alice utilizando esta clave.

La opción 1 anterior utiliza lo que llamaré el modelo SSH donde los clientes generan pares de claves únicos para cada servidor. La opción 2 usa lo que llamaré el modelo SSL donde los servidores tienen el par de claves (aunque SSL comunica la clave pública en un certificado firmado).

Si haces lo anterior tendrás muy buena seguridad. Dicho esto, no será perfecto. El problema es que todavía serás vulnerable a los ataques MiTM .

Para poder trabajar de manera segura, SSH requiere que valide la huella digital de la clave pública del servidor la primera vez que se conecte con ella. El protocolo no explica cómo validar esto. La mayoría de los usuarios solo dicen que está bien sin validar, pero existe la posibilidad de que MITM esté allí.

SSL valida automáticamente la clave pública del servidor al validar la cadena de certificados. Esto solo funciona porque hay un almacén de claves con certificados de raíz de confianza preinstalados con su sistema operativo, navegador u otro cliente. Sin esa validación, la clave pública en el certificado del servidor se puede falsificar sin detección.

No creo que pueda hacerlo mucho mejor a menos que use una infraestructura de seguridad existente. Por ejemplo, puede hacer que su servidor ejecute SSL y que el cliente valide el certificado aprobado en el protocolo de enlace SSL.

No veo esto como un problema, ya que estará tan seguro como SSH cuando el cliente no valide correctamente la clave pública del servidor. OMI, eso es bastante bueno.

Este es un problema muy bueno. ¡Disfruta!

PD: No es necesario que te disculpes por tu inglés. Es tan bueno como un hablante nativo.

    
respondido por el Neil Smithline 19.04.2015 - 00:13
fuente
0

Dependiendo de dónde te encuentres, diría que este es un gran proyecto para la escuela secundaria. La ruta ipsec + dnssec + pki + tls / ssl es en gran medida una faceta basada en el protocolo de este ejercicio. Tal vez le gustaría plantear el aspecto de seguridad física de las cosas también. Por ejemplo, se muestra la ubicación de los puntos finales como un factor de mitigación. Después de todo, los esquifes de nivel Fips para equipos no están ahí para nada.

    
respondido por el mincewind 19.12.2014 - 10:39
fuente
0

Fundamental a la pregunta, es si el punto final no está asegurado, se pueden obtener las claves, lo que sea que puedan ser, por lo que para las transacciones seguras de punto final, el propio terminal está bajo la supervisión del propietario, por ejemplo. cajeros automáticos, puntos de efectivo, etc.

    
respondido por el munchkin 19.04.2015 - 01:39
fuente
0

Buen proyecto, pero como siempre no deberías reinventar la rueda. Escribir tales protocolos para el uso de producción es una mala idea en casi todos los casos. Recomiendo leer el libro de ingeniería de criptografía de Bruce Schneier. No es una lectura ligera, pero definitivamente eliminará todas sus preguntas. En primer lugar, creo que quemar claves en ejecutables es una idea terrible. Debe ser una clave que proteja sus datos confidenciales, no el método (consulte el principio de Kerckhoff). También hace clave la gestión de un PITA. ¿Por qué involucra al servidor en la negociación de claves, es un requisito? Si no me equivoco, usa esa tecla "1234" para la autenticación de pares. Simplemente puede hacer que los clientes lo firmen y verifiquen en el lado del servidor utilizando las claves de cliente. Usted escribió "Una vez que se decida una clave común, use esta clave o un hash de esta clave". Una vez más, la fortaleza clave debe proporcionar seguridad, no el método. Los métodos se pueden reproducir, las claves no.

En general, creo que deberías usar un protocolo bien conocido en lugar de inventar el tuyo. Si solo es un proyecto para aprender protocolos criptográficos, primero recomiendo buscar otros que funcionen.

    
respondido por el djozsef 19.04.2015 - 12:29
fuente
-1

La respuesta (al menos para mi trabajo) es IPsec host to site o host to host con PKI autenticación y protección de las claves privadas en hardware.

    
respondido por el MemCtrl 19.12.2014 - 10:18
fuente

Lea otras preguntas en las etiquetas