Ce défi comporte une prime de 200 points pour le premier à répondre et reste invaincu pendant au moins 3 jours.Réclamé par user3080953 .
Il y a eu beaucoup de discussions ces derniers temps sur le chiffrement de bout en bout, et des pressions sur les entreprises pour le supprimer de leurs produits. Je ne suis pas intéressé par les droits et les torts de cela, mais je me suis demandé: à quel point le code peut-il être court qui inciterait une entreprise à ne pas l'utiliser?
Le défi ici est de mettre en œuvre un échange de clés Diffie Hellman entre deux systèmes en réseau, puis de permettre aux utilisateurs de communiquer dans les deux sens en utilisant la clé symétrique générée. Aux fins de cette tâche, aucune autre protection n'est requise (par exemple, pas besoin de faire défiler la clé, de vérifier les identités, de se protéger contre le DoS, etc.) et vous pouvez supposer un Internet ouvert (tous les ports que vous écoutez sont disponibles pour tout le monde). L'utilisation de builtins est autorisée et encouragée!
Vous pouvez choisir l'un des deux modèles:
- Un serveur et un client: le client se connecte au serveur, puis le serveur ou le client peut envoyer des messages à l'autre. Les tiers entre les deux ne doivent pas être en mesure de lire les messages. Un exemple de flux pourrait être:
- L'utilisateur A lance le serveur
- L'utilisateur B lance le client et le dirige vers le serveur de l'utilisateur A (par exemple via IP / port), le programme ouvre une connexion
- Le programme de l'utilisateur A reconnaît la connexion (en demandant éventuellement à l'utilisateur le consentement préalable)
- Le programme de l'utilisateur B commence la génération d'un secret DH et envoie les données requises (clé publique, prime, générateur, tout ce dont votre implémentation a besoin) à l'utilisateur A
- Le programme de l'utilisateur A utilise les données envoyées pour terminer la génération du secret partagé et renvoie les données requises (clé publique) à l'utilisateur B. À partir de ce moment, l'utilisateur A peut saisir des messages (par exemple via stdin) qui seront cryptés et envoyés à l'utilisateur B (par exemple à stdout).
- Le programme de l'utilisateur B termine la génération du secret partagé. À partir de ce moment, l'utilisateur B peut envoyer des messages à l'utilisateur A.
- Ou: Un serveur avec deux clients connectés: chaque client parle au serveur, qui transmet son message à l'autre client. Le serveur lui-même (et tout tiers intermédiaire) ne doit pas pouvoir lire les messages. Autre que la connexion initiale, le processus est le même que celui décrit dans la première option.
Règles détaillées:
- Vous pouvez fournir un seul programme ou plusieurs programmes (par exemple, serveur et client). Votre score est la taille totale du code dans tous les programmes.
- Votre programme doit être théoriquement capable de communiquer sur un réseau (mais pour les tests, localhost est très bien). Si la langue de votre choix ne prend pas en charge la mise en réseau, vous pouvez la combiner avec quelque chose qui le fait (par exemple un script shell); dans ce cas, votre score est la taille totale du code dans toutes les langues utilisées.
- La génération de clés Diffie Hellman peut utiliser des valeurs "p" et "g" codées en dur.
- La clé partagée générée doit être d'au moins 1024 bits.
- Une fois que la clé est partagée, le choix du chiffrement à clé symétrique vous appartient, mais vous ne devez pas choisir une méthode qui est actuellement connue pour avoir une attaque pratique contre elle (par exemple, un changement de césar est trivial à inverser sans connaissance de la clé ). Exemples d'algorithmes autorisés:
- AES (n'importe quelle taille de clé)
- RC4 (théoriquement cassé, mais pas d'attaques pratiques que je puisse trouver, donc c'est autorisé ici)
- Les utilisateurs A et B doivent tous deux être en mesure de s’envoyer des messages (communication bidirectionnelle) de manière interactive (par exemple, lecture de lignes depuis stdin, invite permanente ou événements tels que l’appui sur un bouton). Si cela facilite les choses, vous pouvez supposer une conversation alternée (c'est-à-dire qu'après qu'un utilisateur a envoyé un message, il doit attendre une réponse avant d'envoyer son prochain message)
- Les extensions de langage sont autorisées (pas besoin d'écrire vos propres méthodes cryptographiques ou réseau si elles sont déjà prises en charge).
- Le format de communication sous-jacent dépend de vous.
- Les étapes de communication données ci-dessus sont un exemple, mais vous n'êtes pas obligé de les suivre (tant que les informations nécessaires sont partagées et qu'aucun intermédiaire ne peut calculer la clé ou les messages partagés)
- Si les détails nécessaires pour se connecter à votre serveur ne sont pas connus à l'avance (par exemple, s'il écoute sur un port aléatoire), ces détails doivent être imprimés. Vous pouvez supposer que l'adresse IP de la machine est connue.
- La gestion des erreurs (par exemple, adresses invalides, connexions perdues, etc.) n'est pas requise.
- Le défi est le golf de code, donc le code le plus court en octets gagne.
p
ilg
autorisé?Réponses:
Node.js (
372423 + 94 = 517513 octets)Golfé
Ajout de sauts de ligne pour la "lisibilité".
chat.js (
423419 octets)Aucun saut de ligne
Sauts de ligne
echo_server.js (94 octets)
Non golfé
Le nœud possède des capacités de mise en réseau et de chiffrement intégrées. Cela utilise TCP pour la mise en réseau (car il est plus simple que l'interface de Node pour HTTP et il fonctionne bien avec les flux).
J'utilise un chiffrement de flux (RC4) au lieu d'AES pour éviter d'avoir à gérer des tailles de bloc. Wikipédia semble penser qu'il peut être vulnérable, donc si quelqu'un a une idée des chiffres à privilégier, ce serait formidable.
Exécutez le serveur d'écho
node echo_server.js
qui écoutera sur le port 9. Exécutez deux instances de ce programme avecnode chat.js <server IP>
etnode chat.js <server IP> 1
(le dernier argument définit simplement lequel envoie un premier). Chaque instance se connecte au serveur d'écho. Le premier message gère la génération de clés et les messages suivants utilisent le chiffrement de flux.Le serveur d'écho renvoie tout simplement à tous les clients connectés, à l'exception de l'original.
Client
Serveur d'écho
Merci Dave pour tous les conseils et commentaires!
la source
Node.js,
638607 octetsMaintenant qu'il est bel et bien battu (et dans la même langue), voici ma réponse de test:
Ou avec emballage:
Usage
Il s'agit d'une implémentation serveur / client; une instanciation sera le serveur, et l'autre le client. Le serveur est lancé avec un port spécifique, puis le client pointe vers le port du serveur. DH peut prendre quelques secondes à configurer si votre machine est faible en entropie, donc les premiers messages peuvent être un peu retardés.
Panne
La seule exigence pour les jetons est qu'ils contiennent au moins un caractère non hexadécimal, donc dans le code minifié, d'autres constantes de chaîne sont utilisées (
data
ethex
).la source