Estaba pensando en la comunicación cliente-servidor y en cómo mantener esto en privado, especialmente de los ataques de intermediarios. Se me ocurrió un esquema que estoy seguro de que ya existe, pero no pude encontrar resultados de búsqueda suficientemente concretos para obtener más información al respecto.
Comencé a pensar que cuando un cliente se conecta al servidor, le gustaría establecer un canal de comunicación seguro, para que el cliente pueda generar un par de claves privada / pública y enviar la clave pública al servidor. El problema es llevar la clave pública al servidor de manera segura (de lo contrario, un hombre en el medio podría descifrar todos los mensajes usando la clave pública que tomó del primer mensaje, adjuntar su propia clave pública al mensaje, usar la clave privada correspondiente para descifrar) la respuesta y, después de almacenar eso, volver a cifrar con la clave pública real del cliente).
Así que pensé en una posible solución: el cliente primero recibe una clave pública del servidor, que utilizará para cifrar su propia clave pública. MitM puede interceptar todos los mensajes, pero no podrá descifrar ninguno de ellos; solo el servidor real puede descifrar la solicitud del cliente y la respuesta solo puede ser descifrada por el cliente real. Una vez que el servidor conoce la clave pública del cliente, la almacenan de forma segura y la utilizan para cifrar cualquier otra comunicación.
Tengo algunas preguntas relacionadas.
- ¿Cómo se llama este tipo de seguridad / handshaking?
- He escuchado la palabra nonce pero tengo razón en que se trata de prevenir los ataques de repetición y no el problema MitM que estoy tratando de resolver.
- La clave inicial que el servidor envía al cliente, ¿debería ser fija y posiblemente publicada en algún lugar, para que los clientes puedan omitir el "dame el paso de tu clave pública" en las sesiones posteriores? ¿O debería ser una clave recién generada para cada cliente en cada nueva solicitud de sesión?
- Por el contrario, ¿debería cambiar la clave pública del cliente con cada sesión o puede reutilizar la misma clave una vez que se haya comunicado de forma segura al servidor?
- ¿Cuáles son los riesgos de esto, aparte de la falla obvia por parte de una de las partes involucradas de mantener privadas las claves privadas?
Estoy seguro de que esto es bastante común y, probablemente, de la forma en que funcionan muchos esquemas de autenticación, así que en lugar de responder todas estas preguntas por separado, me alegraría que alguien me proporcionara la terminología adecuada (probé algunas combinaciones de palabras clave como "cliente / servidor", "cifrado asimétrico", "establecimiento de sesión", pero son demasiado generales para encontrar algo útil). Y aunque esta es una SE teórica, supongo que al igual que con toda la buena seguridad, uno no debe implementar su propia implementación, por lo que cualquier código de ejemplo de una aplicación cliente / servidor adecuada (por ejemplo, en PHP) que utilice bibliotecas bien establecidas sería bienvenido.