Este desafío conlleva una recompensa de 200 puntos para que el primero responda y permanezca invicto durante al menos 3 días.Reclamado por el usuario 3080953 .
Últimamente se habla mucho sobre el cifrado de extremo a extremo y se presiona a las empresas para que lo eliminen de sus productos. No estoy interesado en los aciertos y errores de eso, pero me preguntaba: ¿qué tan corto puede ser el código que presionaría a una empresa para que no lo use?
El desafío aquí es implementar un intercambio de claves Diffie Hellman entre dos sistemas en red, luego permitir a los usuarios comunicarse de un lado a otro utilizando la clave simétrica generada. Para el propósito de esta tarea, no se requieren otras protecciones (por ejemplo, no es necesario cambiar la clave, verificar identidades, proteger contra DoS, etc.) y puede asumir un Internet abierto (cualquier puerto que escuche está disponible para todos). ¡El uso de builtins está permitido y fomentado!
Puede elegir uno de dos modelos:
- Un servidor y un cliente: el cliente se conecta al servidor, luego el servidor o el cliente pueden enviar mensajes al otro. Los terceros entre los dos deben ser incapaces de leer los mensajes. Un ejemplo de flujo podría ser:
- El usuario A inicia el servidor
- El usuario B inicia el cliente y lo dirige al servidor del usuario A (por ejemplo, a través de IP / puerto), el programa abre una conexión
- El programa del usuario A reconoce la conexión (opcionalmente, solicita primero el consentimiento del usuario)
- El programa del usuario B comienza a generar un secreto DH y envía los datos requeridos (clave pública, primo, generador, cualquier otra cosa que su implementación necesite) al usuario A
- El programa del usuario A utiliza los datos enviados para completar la generación del secreto compartido y envía los datos requeridos (clave pública) al usuario B. Desde este punto, el usuario A puede ingresar mensajes (por ejemplo, a través de stdin) que serán encriptados y enviados al usuario B (por ejemplo, stdout).
- El programa del usuario B completa la generación del secreto compartido. Desde este punto, el usuario B puede enviar mensajes al usuario A.
- O bien: un servidor con dos clientes conectados: cada cliente habla con el servidor, que reenvía su mensaje al otro cliente. El servidor en sí (y cualquier tercero intermedio) no debe poder leer los mensajes. Además de la conexión inicial, el proceso es el mismo que el descrito en la primera opción.
Reglas detalladas:
- Puede proporcionar un solo programa o múltiples programas (por ejemplo, servidor y cliente). Su puntaje es el tamaño total del código en todos los programas.
- Su programa debe ser teóricamente capaz de comunicarse a través de una red (pero para las pruebas, localhost está bien). Si su idioma de elección no admite redes, puede combinarlo con algo que sí lo haga (por ejemplo, un script de shell); en este caso, su puntaje es el tamaño total del código en todos los idiomas utilizados.
- La generación de claves Diffie Hellman puede usar valores codificados "p" y "g".
- La clave compartida generada debe ser de al menos 1024 bits.
- Una vez que se comparte la clave, la elección del cifrado de clave simétrica depende de usted, pero no debe elegir un método que actualmente se sabe que tiene un ataque práctico contra ella (por ejemplo, un cambio César es trivial para revertir sin conocer la clave ) Ejemplo de algoritmos permitidos:
- AES (cualquier tamaño de clave)
- RC4 (teóricamente roto, pero no hay ataques prácticos de los que pueda encontrar mención, por lo que está permitido aquí)
- Los usuarios A y B deben poder enviarse mensajes entre sí (comunicación bidireccional) de manera interactiva (p. Ej., Leer líneas de stdin, avisos continuos o eventos como presionar un botón). Si lo hace más fácil, puede asumir una conversación alterna (es decir, después de que un usuario envía un mensaje, debe esperar una respuesta antes de enviar su próximo mensaje)
- Se permiten los idiomas incorporados (no es necesario escribir sus propios métodos criptográficos o de redes si ya son compatibles).
- El formato de comunicación subyacente depende de usted.
- Los pasos de comunicación dados anteriormente son un ejemplo, pero no es necesario que los siga (siempre y cuando se comparta la información necesaria y ningún intermediario pueda calcular la clave o los mensajes compartidos)
- Si los detalles necesarios para conectarse a su servidor no se conocen de antemano (por ejemplo, si escucha en un puerto aleatorio), estos detalles deben imprimirse. Puede suponer que se conoce la dirección IP de la máquina.
- No se requiere el manejo de errores (por ejemplo, direcciones no válidas, conexiones perdidas, etc.).
- El desafío es el código de golf, por lo que gana el código más corto en bytes.
p
yg
permitido?Respuestas:
Nodo.js (
372423 + 94 = 517513 bytes)Golfed
Saltos de línea agregados para "legibilidad".
chat.js (
423419 bytes)Sin saltos de línea
Saltos de línea
echo_server.js (94 bytes)
Sin golf
Node tiene capacidades integradas de red y criptografía. Esto utiliza TCP para la creación de redes (porque es más simple que la interfaz de Node para HTTP, y funciona muy bien con las transmisiones).
Utilizo un cifrado de flujo (RC4) en lugar de AES para evitar tener que lidiar con los tamaños de bloque. Wikipedia parece pensar que puede ser vulnerable, por lo que si alguien tiene alguna idea de cuáles son las cifras preferidas, sería genial.
Ejecute el servidor echo
node echo_server.js
que escuchará en el puerto 9. Ejecute dos instancias de este programa connode chat.js <server IP>
ynode chat.js <server IP> 1
(el último argumento solo establece cuál envía un primo). Cada instancia se conecta al servidor echo. El primer mensaje maneja la generación de claves, y los mensajes posteriores usan el cifrado de flujo.El servidor de eco simplemente envía todo de vuelta a todos los clientes conectados, excepto el original.
Cliente
Servidor de eco
Gracias Dave por todos los consejos + comentarios!
fuente
Nodo.js,
638607 bytesAhora que ha sido bien derrotado (y en el mismo idioma), aquí está mi respuesta de prueba:
O con envoltura:
Uso
Esta es una implementación de servidor / cliente; una instancia será el servidor y la otra el cliente. El servidor se inicia con un puerto específico, luego el cliente apunta al puerto del servidor. DH puede tardar unos segundos en configurarse si su máquina tiene poca entropía, por lo que los primeros mensajes pueden retrasarse un poco.
Descompostura
El único requisito para los tokens es que contengan al menos un carácter no hexadecimal, por lo que en el código minificado se usan otras constantes de cadena (
data
yhex
).fuente