Primero, sugiero evitar los supuestos sobre la sobrecarga de cifrado. Debes medir . Mi PC desde 2001 ya era lo suficientemente potente como para transferir datos con SSH a la velocidad máxima de un enlace de 100 Mbit / s, con cifrado. Mi PC real, un Core2 común a 2.4 GHz, puede hacer un cifrado AES a 167 Mbytes por segundo (sí, megabytes , no megabits), más que suficiente para Gigabit Ethernet, y eso está usando un solo núcleo. - Tengo otros tres núcleos.
Si desea autenticar un cliente, el cliente debe debe tener algo especial que el usuario malintencionado previsto no tiene. Hablando criptográficamente, algunos datos secretos, que llamaremos una clave , porque esas son las claves: un fragmento de datos secretos, utilizados en un algoritmo que se supone no secreto. Tenga en cuenta que esto conlleva una falla estructural que no se puede evitar realmente: cualquier persona con acceso de lectura al código del cliente puede realizar ingeniería inversa y recuperar la clave. Esto se puede hacer un poco más difícil a través de técnicas de ofuscación de código, pero no hasta el punto de hacerlo imposible.
Además, desea autenticar la conexión , es decir, no solo el acto de iniciar el túnel de datos, sino también los datos que realmente se transfieren. De lo contrario, el atacante podría secuestrar la conexión una vez que se haya realizado el paso de autenticación. Esto implica el uso de una verificación de integridad criptográfica, que se denomina MAC . En ese punto, agregar cifrado es fácil. SSH utiliza tanto el cifrado simétrico como un MAC.
Fuera de los bloques de construcción existentes, sugiero las siguientes soluciones:
-
Use SSH. El cliente se conecta a través de SSH y utiliza una contraseña codificada para autenticarse (la contraseña es la clave que mencioné anteriormente). El mecanismo habitual de SSH evita los usuarios intermedios, es decir, el cliente SSH debe guardar una copia de la clave pública del servidor.
-
Use SSL / TLS. Esto es muy similar a lo que sucede con SSH. El cliente sabe que habla con el servidor correcto porque la clave pública del servidor se presenta como parte de un certificado X.509, que está firmado y puede ser validado por el cliente. El cliente debe tener conocimiento de la clave pública de la autoridad de certificación. Alternativamente, el cliente ya puede conocer el certificado del servidor y simplemente verificar que este sea el mismo certificado que el enviado por el servidor. Una vez que se establece el túnel, con el cifrado y las comprobaciones de integridad, el cliente puede simplemente enviar su clave "tal cual" para probar su identidad.
-
Use SSL / TLS con un certificado de cliente. En esta configuración, el cliente tiene un par de claves pública / privada. La clave privada es la clave de la que estaba hablando. La clave pública se codifica en un certificado que el cliente muestra durante el protocolo de enlace SSL. Todo esto es material SSL estándar, por lo tanto, es compatible con las bibliotecas SSL existentes. En comparación con la solución 2, esto evita la necesidad de incluir un mensaje de envío de clave en su protocolo de aplicación, y también permite el uso de conjuntos de cifrado solo para MAC, en caso de que resulte que el cifrado sea demasiado costoso computacionalmente (lo cual dudo) .
-
Use la clave del cliente en un Cambio de clave autenticado por contraseña para obtener una clave de sesión común , luego se utiliza para un MAC (y posiblemente encriptación). El punto de los protocolos PAKE es que pueden tolerar secretos de baja entropía, es decir, contraseñas que encajan en el cerebro de los usuarios humanos. La ejecución de un túnel con MAC tiene algunas sutilezas, por lo que la forma correcta es utilizar un protocolo existente. A continuación, esto requiere TLS con SRP . La "contraseña" está codificada en el cliente (y aunque SRP tolera contraseñas cortas, nada le impide usar una contraseña larga y muy aleatoria). La belleza de la cosa es que esto suprime cualquier eliminación con certificados o claves públicas conocidas. El cliente se autentica en virtud de su conocimiento de la contraseña. Al mismo tiempo, el servidor es también autenticado por contraseña por el cliente. Como beneficio adicional, con SRP, el servidor solo almacena una parte de los datos derivados de la contraseña, que el cliente no puede utilizar directamente, por lo que un atacante que lee la base de datos del servidor no obtiene acceso automático como "cliente".
Mi solución favorita es, por supuesto, la que tiene SRP. Es elegante . Desafortunadamente, SRP es bastante nuevo, por lo que no todas las implementaciones de SSL / TLS lo soportan. Pero GnuTLS sí.