Knod Box 0.3
Divulgâchage : Comment fonctionnent ces énigmes hors ligne ?
Dans mon post précédent, je vous ai présenté l'idée qui trottait dans ma tête depuis pas mal de temps. Un système d'énigmes qu'on puisse jouer hors ligne et avec lequel on puisse prouver avoir résolu une énigme sans dévoiler la réponse...
J'avais volontairement passé sous silence les explications du comment ça marche pour vous permettre de le découvrir par vous même. Je penses que tous ceux qui voulaient le découvrir ont eu le temps de le faire et que je peux maintenant vous expliquer les détails, pour que tous les autres puissent le découvrir aussi.
Mais avant d'entrer dans les détails, voici la nouvelle version de la Knod Box d'initiation. C'est encore une image PNG que vous pouvez télécharger dès à présent, comme ça vous pourrez appliquer les explications directement.
Un PNG Polyglotte
Je voulais que les Knod Box soient des fichiers autonomes. Qu'elles contiennent tout ce qu'il faut pour pouvoir jouer hors ligne. J'aurais pu faire une archive zip ou tarball,... mais je trouvait ces formats trop austères et pas assez photogéniques.
J'ai donc choisi de détourner le format PNG pour y intégrer tout ce dont j'avais besoin pour ma mécanique de jeu. Les Knod Box sont donc des images classiques qu'on peut visualiser sur un site web (comme ici) ou dans un répertoire. Mais en même temps, ces images cachent, dans des zones spécifiques dont on va parler plus tard, tout le matériel de jeu pour la partie.
Pour jouer, je vous ai codé un Knod Pick. Une petite application qui se charge d'extraire le matériel et vous permet de tester des réponses, les vérifier, générer des preuves de réussite et vérifier celles des copains. L'application et en HTML et JS vanilla pour que vous n'ayez besoin que d'un navigateur web pour jouer1.
Reste le problème de la diffusion de mon knod Pick. Je pourrais héberger ces fichiers ici (ou dans un sous-domaine), voir vous filer un lien vers le ZIP qui les contient... mais l'idée de base, c'était de jouer hors ligne ; que la Knod Box contienne tout ce dont elle a besoin...
Heureusement, un de mes petits détournements du format PNG me permet de transformer n'importe quelle image en conteneur de fichiers... J'ai donc incorporé mon ZIP dans mon PNG. Le PNG contient donc l'application qui permet de jouer avec le PNG.
Vous pouvez extraire cette application que j'ai caché dans le PNG via l'application que j'ai caché dans le PNG.
Le truc génial dans cette histoire, c'est que la façon d'incorporer le ZIP dans le PNG l'a rendu polyglotte. Pour le système (et la plupart des applications), le fichier est un PNG et ils vous affichent l'image. Mais pour les logiciels de (dé)compression, le fichier est un ZIP et ils pourront vous extraire son contenu directement...
Sous GNU/Linux, ouvrez une invite de commande et utilisez simplement unzip :
unzip <fichier>.png
Avec 7zip, commencez par renommer le fichier en remplaçant l'extension .png par .zip. Vous pouvez ensuite faire un clic droit et choisir 7-zip / Ouvrir archive > / zip pour ouvrir le fichier comme une archive (et extraire son contenu). Sinon en ligne de commande :
7z.exe x -tzip <fichier>.zip
Avec cmd / PowerShell, vous pouvez utiliser la commande tar comme suit :
tar -xf <fichier>.png
Il y a sûrement bien d'autres manières d'extraire le Knod Pick suivant vos distributions et vos logiciels de décompression mais dans tous les cas, vous obtiendrez un répertoire avec le fichier HTML, son style en CSS et quelques fichiers Js pour manipuler la Knod Box.
Ouvrez alors index.html et vous aurez une dropzone pour y mettre la Knod Box (ou une autre). L'application s'occupera de trouver le matériel de jeu et vous l'affichera. L'application s'occupera de valider vos réponses, générer les preuves de réussite, et vérifier celles des copains.
Descendez vers la fin du fichier et l'application vous permettra d'extraire le ZIP et son application cachés dans le PNG...
Un PNG étendu
Ce qu'il y a de bien avec le format PNG, c'est qu'il est relativement facile à étendre. Les détails sont dans la spec, mais globalement, une fois passé les 8 premiers octets qui disent "ceci est un PNG", le reste est une suite de chunks qui se présentent tous de la même manière :
- La taille du contenu du chunk sur 4 octets (gros boutistes),
- Le type de chunk (4 caractères alphabétiques),
- Les données du chunk, le format dépend du type,
- Le CRC-322 calculé sur le type et les données.
La spécification défini des types de chunks essentiels pour stocker des images (e.g. la couleur des pixels) mais nous laisse définir nos propres types tant qu'on respecte quelques contraintes (en gros, ils ne peuvent pas être critiques).
Mes chunks custom
J'en ai donc défini quelques uns de mon cru...
fiLe : qui associe un nom de fichier avec le contenu du fichier. Ça transforme le PNG en conteneur de fichiers. Je peux ainsi joindre des fichiers aux énigmes. C'est dans un de ces file que j'ai incorporé le ZIP contenant l'application.
ceNc : qui stocke un groupe de chunks chiffrés qu'on peut débloquer avec un mot de passe (la solution d'une énigme) ou une clé cryptographique (qu'on obtient en résolvant d'autres énigmes).
Ces chunks servent à plein de choses. Constituer des répertoires pour grouper les chunks par énigme, stocker des informations utiles en cas de réponse presque bonne du joueur, marquer une étape intermédiaire dans une énigme...
csIg : qui signe les chunks qui le précèdent et embarque le certificat de la clé qui a signé et sa chaîne de confiance pour pouvoir vérifier la signature en connaissant uniquement la racine. Je m'en sert pour certifier l'authenticité de mes Knod Box.
knOd : qui stocke une clé cryptographie chiffrée, déblocable avec un mot de passe (solution d'une énigme) ou par une autre clé. La plupart du temps, je m'en sert pour stocker la clé privée d'un certificat...
ceRt : qui embarque un certificat et sa chaîne de confiance. Trouvez la clé privée de ce certificat (cachée dans un knod) et vous pourrez l'utiliser pour signer vos badges de réussite...
kbDg : qui représente les badges de réussite. Il contient le message d'un joueur, sa signature par la clé qu'il a trouvé ainsi que le certificat et sa chaîne de confiance qui permet de vérifier l'authenticité du badge.
Les algos crypto
L'application HTMl+JS est faite pour vous permettre de jouer sans avoir besoin comprendre quoi que ce soit à la crypto mais pour les curieux, voici ce que j'ai mis dedans...
PBKDF2 pour dériver des clés à partir des réponses aux énigmes. C'est plus pratique que SHA512 car je peux jouer avec le nombre d'itération pour gêner les brutes force. J'aurais bien utilisé argon2 mais elle n'est pas disponible en Vanilla JS.
AES-GCM pour chiffrer des chunks (dans des cenc) ou des clés (dans des knod). L'avantage c'est que ce mode fourni un contrôle d'authenticité qui vous dira si la réponse fournie est bonne ou pas.
Ed25519 pour signer des chunks (dans les csig) et des messages (dans les certificats et les badges) et bien sûr, vérifier que ces signatures sont valides.
X25519 pour générer des secrets partagés. Je l'utilise pour chiffrer des contenus à destination d'une clé publique. Lisible uniquement par les joueurs ayant découvert la clé privée correspondante.
D'autres algorithmes sont prévus mais vous avez là les principaux ; ceux que j'utilise le plus.
Et après ?
Avec PBKDF2 et AES-GCM, l'application peut vérifier les réponses fournies par les joueurs et débloquer l'accès à d'autres chunks (via un cenc) ou une clé cryptographique (via un knod). Avec Ed25519 et les certificats, la découverte de la clé privée permet de fabriquer une preuve de réussite (un badge kbDg) sans dévoiler la réponse, et vérifiable hors ligne avec cette CA :
TGVzIGFyc291eWVzIFJvb3QgQ2VydGlmaWNhdGUA
UHUTjaCwC1tjtOwynMWTVZwH7YUUW8ZBxYyrkc3k
SN4DiFkgFNU8Yv75YOK0ESKeW8vfCbmKmK9dVPDj
S4s9/6ySv/x1ly9xy/+mhRLF8lz8t2vxcdUaeN8N
Lv49zp5bCw==
Si vous avez aimé la Knod Box d'initiation, ou si vous voulez voir un autre type d'énigmes qu'on peut y intégrer, voici une deuxième Knod Box :
Téléchargez ce fichier sur votre disque dur, dézipper l'application (ou réutilisez celle de la Knod Box d'initiation) et vous pourrez jouer avec la suite de Syracuse, partager vos badges et vérifier ceux des copains.
Pour les curieux, et ceux qui voudraient développer leurs propres outils, le ZIP que j'embarque dans les Knod Box contient, en plus du Knod Pick, la spécification du format. Vous y trouverez tous les détails que j'ai pensé à décrire (format des données et description des algorithmes)3.
De même, le code JS de l'application n'est pas minifié. Je l'ai écrit pour que vous puissiez le lire et l'adapter au besoin. Par contre, gardez à l'esprit que j'ai appris à coder en JS il y a trois semaines pour l'occasion4.
Dernier avertissement (mais pas des moindres), j'en suis encore à fixer le format et vous devriez donc le considérer comme en phase de test. Le Knod Pick en version 0.2 ne pourra pas comprendre la version 0.3. Et il est très probable que la 0.3 ne soit pas complètement compatible avec la 0.4 car j'ai encore des choses à intégrer. N'hésitez pas à nous contacter si vous voulez être dans la boucle.
Par contre, le format des badges ne changera pas et ils resteront donc vérifiables. N'hésitez surtout pas à les partager ;-)