loader

Kit cyber - Chapitre 13 : Communication par messages chiffrés

Premier chapitre du parcours certificats et tiers de confiance du kit cyber

Pendant des siècles, la cryptographie a reposé sur un principe unique : le chiffrement symétrique. Que ce soit le Chiffre de César dans l'Antiquité ou la machine Enigma durant la Seconde Guerre mondiale, il fallait toujours que l'émetteur et le destinataire partagent le même secret (la clé de chiffrement). Le problème majeur, appelé "problème de la distribution des clés", était le suivant : comment transmettre cette clé secrète de manière sécurisée sans qu'elle soit interceptée ? C'était le point faible du système. La réponse a été popularisée par le monde académique.

En 1976, deux chercheurs américains, Whitfield Diffie et Martin Hellman, conceptualisent pour la première fois l'idée de chiffrement asymétrique : une paire de clés où ce qui est chiffré par l'une ne peut être déchiffré que par l'autre. C'est un an plus tard que la théorie est mise en pratique. Ron Rivest, Adi Shamir et Leonard Adleman (d'où le sigle RSA) du MIT inventent le premier algorithme de chiffrement asymétrique véritablement fonctionnel.

Pour explorer ces notions de manière concrète, nous allons mettre en œuvre une simulation à l'aide de cartes micro:bit. Ce dispositif nous permettra de modéliser des échanges sécurisés entre Alice (qui joue le rôle d’une entité “cliente”) et Bob (qui joue le rôle d’une entité serveur, un service de banque par exemple). Alice et Bob sont des personnages fictifs utilisés en cryptographie pour représenter simplement deux entités qui communiquent, à la place de « personne A » et « personne B ».
Lors de cette simulation, les deux dispositifs utiliseront une implémentation simplifiée de l'algorithme de chiffrement asymétrique RSA. L'objectif est de visualiser le principe de base du chiffrement asymétrique et, surtout, identifier son point de vulnérabilité : la confiance accordée à une clé publique.

Pour protéger un message, on peut utiliser deux types de chiffrement :
  • Le chiffrement symétrique : On utilise la même clé pour fermer et ouvrir un cadenas. C'est simple et rapide, mais cela pose un gros problème : comment envoyer la clé secrète à son correspondant sans qu'elle soit interceptée ?
  • Le chiffrement asymétrique : C'est comme une boîte aux lettres.
    • La clé publique est comme la fente de la boîte. Tout le monde peut l'utiliser pour y glisser un message (pour chiffrer).
    • La clé privée est la clé physique qui ouvre la boîte. Seule une personne (le propriétaire) peut l'utiliser pour récupérer les messages et les déchiffrer.


L’avantage : plus besoin d’échanger un secret au préalable. Alice peut utiliser librement la clé publique de Bob pour lui envoyer un message chiffré. Et seul Bob, avec sa clé privée, pourra lire les messages.
L'algorithme RSA est un système célèbre qui fonctionne sur ce principe. Sa force réside dans des calculs mathématiques très complexes qui rendent extrêmement difficile en pratique de deviner la clé privée même si on connaît la clé publique. Pour comprendre les concepts mathématiques qui font la force du chiffrement RSA, un chapitre bonus est disponible à la fin de ce parcours.

La première étape du programme va être de générer une paire de clés RSA. Le bloc qui permet de générer les clés est le suivant :

bloc génération clés RSA

Ce bloc génère une paire de clés (publique et privée) et permet de choisir leur taille. Plus la taille est grande, plus la sécurité augmente, mais plus la génération et le chiffrement/déchiffrement sont lents. Sur micro:bit, on se limite à 32 (contre 2048 ou 4096 pour RSA en pratique). Le bloc renvoie une liste : clé publique en premier, clé privée en second.

Ensuite, il va falloir demander la clé publique du serveur. En effet, pour pouvoir transmettre des données de manière chiffrée, il faut d’abord chiffrer son propre message avec la clé publique du destinataire. Ainsi, il sera le seul à pouvoir le déchiffrer grâce à sa clé privée.
On va définir une requête, nommée CLE. Le client va envoyer ce message au démarrage du programme, en fournissant en valeur sa propre clé publique, pour que le serveur puisse lui aussi récupérer la clé publique du client.
Le client devra également écouter les messages entrants pour récupérer la réponse du serveur, et stocker la clé publique de celui-ci dans une variable.

Attention cependant, tous les messages radio ne peuvent transmettre que des primitifs (chaînes de caractères, nombres entiers, à virgule, etc.). La clé va donc être transmise sous la forme de chaîne de caractères, et non de liste Python, via le bloc ci-dessous :

bloc conversion texte

Il va ensuite falloir utiliser une instruction pour reconvertir la chaine de caractères en tableau. On va utiliser une instruction spéciale, qui permet d’exécuter du code Python sous la forme de chaîne de caractères, pour pouvoir reconstruire la liste à partir de la chaîne de caractères. Ce bloc est le suivant :

conversion texte en liste

Ce bloc exécute le code Python cle_serveur = (1234, 5678), dans le cas où la clé du serveur est (1234, 5678). Attention, ce bloc est ici utilisé pour faciliter la création du programme. Comme vu durant le parcours injection de code, on n’exécute jamais du code utilisateur en temps normal.

Attention - Pour tous les programmes de ce parcours, il faut configurer la radio en utilisant le bloc associé, afin de définir la taille des messages à 250. Dans le cas inverse, les programmes risquent de ne pas fonctionner.


Si tu es bloqué :
  • Vérifie que le client et le serveur sont sur le même canal / groupe radio et qu’ils exécutent bien le bloc de génération de clés RSA au démarrage.
  • Assure-toi que tu récupères correctement la paire de clés : l’élément 0 de la liste dans cle_publique, l’élément 1 dans cle_privee, et que le message CLE contient bien la clé publique (en texte).
  • À la réception d’un message CLE, le client comme le serveur doivent stocker la clé reçue ; si tu utilises le bloc d’exécution de code Python pour reconstruire la clé à partir de la chaîne, affiche temporairement name, value et les variables de clés dans la console pour voir où ça coince.

La carte serveur va devoir, elle aussi, générer une paire de clés RSA à son démarrage. Cependant, elle n’a pas besoin d’envoyer de messages au démarrage, juste de recevoir et de traiter les messages reçus par le client. Elle devra cependant envoyer sa propre clé lorsque le client lui demandera. À partir du programme de la carte client, vous pouvez implémenter la carte serveur.


Si tu es bloqué :
  • Vérifie que le client et le serveur sont sur le même canal / groupe radio et qu’ils exécutent bien le bloc de génération de clés RSA au démarrage.
  • Assure-toi que tu récupères correctement la paire de clés : l’élément 0 de la liste dans cle_publique, l’élément 1 dans cle_privee, et que le message CLE contient bien la clé publique (en texte).
  • À la réception d’un message CLE, le client comme le serveur doivent stocker la clé reçue ; si tu utilises le bloc d’exécution de code Python pour reconstruire la clé à partir de la chaîne, affiche temporairement name, value et les variables de clés dans la console pour voir où ça coince.

Maintenant que les clés sont échangées, il est possible pour Alice et Bob d’échanger des messages chiffrés. Voici le déroulé d’un échange :
  • Alice chiffre son message avec la clé publique de Bob.
  • Alice envoie son message que Bob reçoit.
  • Bob déchiffre le message grâce à sa clé privée, et traite le message.
  • Si Bob doit renvoyer un message, il le chiffre avec la clé publique d’Alice, et envoie le message. Alice reçoit alors le message qu’elle peut déchiffrer avec sa clé privée.

Comme les messages sont chiffrés avec la clé publique du destinataire, seule la personne possédant la clé privée du destinataire (le destinataire lui-même donc) peut déchiffrer le message chiffré. C’est de cette manière que la confidentialité des échanges est garantie.
Dans notre cas, il existe deux blocs qui permettent de respectivement chiffrer et déchiffrer les messages :

Blocs chiffrement / déchiffrement RSA

On va mettre en place deux nouveaux types de requête, qui vont permettre au client de stocker un mot de passe sur le serveur, et de récupérer ce mot de passe à la demande. Les deux types de requête seront MDP_SET (set = définir en anglais) et MDP_GET (get = récupérer en anglais). Les requêtes de type MDP_SET envoyées par le client devront contenir le mot de passe chiffré, tandis que les requêtes MDP_GET pourront ne pas contenir de valeur particulière. Les messages devront aussi avoir leur clé (type de requête) et leur contenu tous deux chiffrés, afin de prévenir toute lecture par un tiers.
On fera en sorte que l’appui du bouton A déclenche la sauvegarde du mot de passe, et le bouton B sa récupération.


Si tu es bloqué :
  • Vérifie que la génération et l’échange de clés ont bien eu lieu avant d’envoyer un message : les variables qui stockent la clé publique de l’autre carte ne doivent plus être à 0 ou vides.
  • Assure-toi que tu chiffres le message avec la clé publique du destinataire avant de l’envoyer, et que tu le déchiffres avec ta clé privée à la réception.
  • Pour déboguer, affiche dans la console le message en clair, le message chiffré (suite de nombres) et, côté réception, le résultat du déchiffrement : tu dois retrouver exactement le texte de départ.

De la même façon que la carte client, la carte serveur va devoir chiffrer / déchiffrer les messages sortants / entrants grâce à la clé publique de la carte client / sa propre clé privée pour répondre aux requêtes envoyées par le client.
Lorsque la carte serveur recevra une requête MDP_SET, elle devra sauvegarder le mot de passe reçu dans une variable, et renvoyer une requête MDP_SET sans contenu pour indiquer à la carte client que le mot de passe est bien sauvegardé.

Lorsque la carte serveur recevra une requête MDP_GET, elle devra renvoyer dans une autre requête MDP_GET le mot de passe sauvegardé.


Si tu es bloqué :
  • Vérifie que la génération et l’échange de clés ont bien eu lieu avant d’envoyer un message : les variables qui stockent la clé publique de l’autre carte ne doivent plus être à 0 ou vides.
  • Assure-toi que tu chiffres le message avec la clé publique du destinataire avant de l’envoyer, et que tu le déchiffres avec ta clé privée à la réception.
  • Pour déboguer, affiche dans la console le message en clair, le message chiffré (suite de nombres) et, côté réception, le résultat du déchiffrement : tu dois retrouver exactement le texte de départ.

Téléverse le programme de génération + échange de clés sur les deux cartes, puis celui d’échange de messages chiffrés sur le client et le serveur, en vérifiant qu’ils sont sur le même canal radio. Au démarrage, laisse le temps aux cartes d’échanger leurs clés publiques. Ensuite, depuis la carte client, envoie un message (par exemple en appuyant sur un bouton) : la carte serveur doit afficher ce message en clair, alors que la console montre qu’il a circulé sous forme de texte chiffré (suite de nombres). Tu peux essayer avec plusieurs messages différents pour vérifier que tout fonctionne.

Dans ce premier chapitre, nous avons mis en place une véritable conversation chiffrée entre Alice et Bob, en nous appuyant sur une version simplifiée de RSA. La génération de clés, leur échange via les messages radio, puis l’envoi de mots de passe chiffrés nous ont permis de voir concrètement comment le chiffrement asymétrique résout le vieux problème de la distribution des clés : la clé publique peut être diffusée librement, tandis que la clé privée reste secrète et permet seule de déchiffrer les messages reçus.

Mais cette activité met aussi en lumière un point de fragilité important : tout le système repose sur la confiance accordée à la clé publique. Si quelqu’un parvient à se faire passer pour Bob (le serveur légitime) et à diffuser sa propre clé publique à la place, il pourra lire les messages destinés au vrai Bob. Autrement dit, chiffrer ne suffit pas, il faut aussi être sûr de l’identité de celui à qui l’on parle.

Pour aller plus loin :
  • Chercher les mots-clés « chiffrement asymétrique », « RSA » et « clé publique / clé privée » pour mieux comprendre comment ce type de chiffrement est utilisé sur Internet.
  • Se renseigner sur les certificats numériques et sur les protocoles HTTPS / TLS, qui s’appuient sur ces mécanismes pour sécuriser les échanges entre un navigateur et un site web.

User licence