Aller au contenu
AFUP AFUP Day 2024 Baromètre Planète PHP PUFA
 

Comment fonctionne la cryptographie ?

Description

Cette présentation va montrer la base commune derrière tout processus cryptographique informatique. Nous parlerons du chiffrement de Vernam, appliqué dans la machine Enigma à l'époque, pour l'appliquer au domaine de l'informatique.

Nous verrons une implémentation précise de la notion de chiffrement : le chiffrement par flot et les registres à décalage. Ces structures sont derrière la notion d'aléatoire en informatique. Le but est que tout le monde comprenne bien techniquement, comment fonctionne la base de tous les algorithmes de cryptographie du monde, sans pour autant entrer dans des formules mathématiques incompréhensibles.

Nous coderons une machine de chiffrement par flot, pas à pas, en PHP, puis sous forme d'extension PHP (en C). Les (vieux) algorithmes RC4 et A51 seront analysés puis implémentés pas à pas à titre d'exemple dans des classes PHP.

Conférence donnée lors du Forum PHP 2018, ayant eu lieu les 25 et 26 octobre 2018.

Informations complémentaires

Vidéo

Le speaker

Julien PAULI

Julien PAULI est un architecte système et web qui travaille chez SensioLabs. Véritable passionné par l'openSource, il s'investit et contribue à l'amélioration quotidienne de PHP et de son écosystème, en corrigeant des bugs et en développant des idées/concepts via des extensions. Il a été en charge de la gestion des sorties des versions 5.5 et 5.6 du langage.

Commentaires

Super intéressant, mais un monde à part entière !
Yohann Marillet, le 26/10/2018
Merci Julien. Toujours l'impression de me retrouver à l'école quand j'assiste à tes conf. Super intéressant. Le double du temps aurait été bien pour approfondir !
jeremyFreeAgent (Jérémy Romey), le 29/10/2018
Excellente introduction merci ! Par contre, si j'ai eu l'impression de prendre les idées générales, je suis impatient que les diapo soient publiées pour que je revoie tout ça dans le détail : le rythme était vraiment trop rapide ! Le sujet était dense certes mais un meilleur compromis entre vitesse et info délivrées aurait été bienvenu.
Pierre Goiffon, le 05/11/2018

Transcript

Bonjour, bonjour à tous donc.

Donc les bases de la crypto, alors...

Sur ce talk, il faut bien voir un truc, c'est qu'on ne va pas... On a 40 minutes à peu près, un peu moins, bon...

Un peu plus, ça dépend. On ne peut pas expliquer tout.

TLS, toutes ces choses-là, voilà.

En fait, ce que j'ai voulu faire sur ce talk, c'est montrer comment...

comment ça fonctionne, et comment toute la crypto fonctionne.

C'est à dire la base même, tout en bas, de ce qui arrive. On va voir, c'est super simple en fait.

Après, on va mettre des formules mathématiques et plein de choses, mais qu'on ne verra pas sur ce talk.

Pas des choses trop compliquées.

Et puis, comment implémenter 2,3 algos, et puis le principe même de la crypto, implémenté avec, donc des designs en PHP et en C derrière, OK ? Voilà à peu près comment ça va marcher. Et puis on parlera aussi des DVD, on parlera du wifi, de partout où c'est appliqué.

Il n'y a pas que sur https qu'on voit de la crypto, on en voit partout, et donc, c'est toujours le même principe.

Tout en bas, ça fonctionne de la même manière.

Après, au-dessus, on va empiler plein de choses qui font que ça peut se complexifier, mais de manière générale, le principe, c'est toujours le même. Il est basé sur ce qu'on appelle le principe de Vernam et l'OTP. Donc, c'est la seule manière, mathématiquement, absolument 100% sûre, de chiffrer quelque chose et de le rendre indéchiffrable.

Il n'y a qu'une seule manière, c'est celle-là.

Et donc, tous les algos, de toute la crypto du monde, fonctionnent sur ce principe-là.

Ce principe-là dit quoi ? Il dit que j'ai un texte en clair, et j'utilise une opération mathématique simple, avec une clé.

On verra qu'il doit faire la même taile, blablabla, et j'obtiens quelque chose qui est chiffré, d'accord ? Donc, en fait, on additionne modulo la base qu'on utilise, la clé, qu'on va choisir de manière aléatoire, on va voir ça. Et on additionne ça avec le clair, et on obtient du chiffré et c'est parfaitement objectif, puisqu'on sait que l'addition, on utilise une soustraction, et on revient. Donc, c'est à dire qu'on a la clé plus le chiffré et on revient sur le clair.

D'accord ? Donc c'est à peu près ça le principe super simple de Vernam, et ce principe-là, il dit que si j'ai que le chiffré, et que je n'ai pas la clé, et bien je ne peux pas retrouver le clair. C'est impossible, voilà.

C'est tout.

C'est vraiment super simple. En plus, on va voir que c'est une addition qu'on fait.

Alors, si j'applique ça avec des images, Donc, je prends une image qu'on voit bien, je prends une clé qui fait la même taille que l'image, et quand j'utilise l'addition de Vernam, Et bien j'obtiens quelque chose qui est complètement indéchiffrable.

On est tous d'accord, OK ? Voilà, donc, c'est magique, Vernam.

C'est juste fou.

Cependant, ça ne fonctionne que sous certaines conditions.

Les quatre conditions, c'est que la clé doit être aléatoire et ne puisse pas être devinée.

La deuxième condition, c'est que la clé doit rester secrète, une fois qu'elle a été générée.

La troisième condition, c'est que la clé doit avoir une taille qui est au moins égale à la taille de ce qu'on veut chiffrer, à ce qui est clair.

Donc la quatrième condition, celle où j'en étais donc, la clé ne doit jamais être réutilisée.

Et vu que la même clé est utilisée pour chiffrer et pour déchiffrer, on appelle ça du chiffrement symétrique.

Et je n'irai pas plus loin sur ce principe-là, l'asymétrique, le symétrique, etc.

Très important : la clé ne doit pas être réutilisée.

Parce que si on réutilise la clé, voilà ce qu'il se passe.

Je chiffre un premier clair avec la clé, je chiffre un 2e clair avec la même clé, j'obtiens donc deux chiffrés. Et en utilisant la même opération entre les deux chiffrés, et bien, je vais obtenir la même opération entre les deux clairs.

Le problème-là, il a été...

Il y a une anecdote de ce problème-là sur Microsoft.

Je n'irai pas plus loin mais bon. En gros ici, Ils utilisaient ça dans de vieux documents Word 2000, etc, et donc vous en chiffriez deux, vous aviez les deux chiffres et vous faisiez un XOR entre les deux et vous récupériez un caractère sur deux, qui faisait partie d'un texte sur deux, vous coupiez et vous aviez les deux clairs.

OK ? Donc on ne réutilise jamais la même clé, d'accord ? Alors, quand est-ce que ça a été inventé ? Quand est-ce que ça a été utilisé ? Petit historique, ce principe-là, il a été utilisé avec Enigma, OK ? Lors de la deuxième guerre mondiale, et puis il a été utilisé dans le téléphone rouge. A l'époque, c'était...

Les clés étaient physiques, elles étaient donc dans des grosses grosses valises qui étaient super sécurisées.

On mettait la clé dans un téléphone, la clé dans l'autre, ça chiffrait d'un côté, ça déchiffrait dans l'autre, c'était génial.

Voilà. Appliquée à l'informatique, L'opération qu'on utilise, c'est l'addition Modulo 2, et l'addition Modulo 2, c'est le XOR.

c'est le OU exclusif, donc voici la table de vérité.

Donc qui est noté un petit + entouré, c'est un peu bizarre, décalé, et/ou un petit chapeau. Donc, c'est l'opération qu'on utilise en informatique pour chiffrer. Et elle est super simple, c'est XOR.

Donc si on A qui est clair, et si on a B qui est notre secret. Et bien, si on fait A ^ B, on obtient le chiffré C.

et si je reprends mon chiffré C et que je fais un XOR avec ma clé B, je retrouve mon clear A.

Voilà, c'est super. C'est ce qu'on appelle la crypto symétrique, et ça marche sur ça. Ca marche exactement comme ça. Sauf que, c'est bien joli, mais ces quatre conditions quand on les applique à l'informatique, elles sont particulièrement difficiles à mettre en place.

Alors on va les étudier une à une. Et on va voir les solutions qu'on a, pour trouver comment faire pour que ça puisse fonctionner. Donc la clé doit être secrète, ça, c'est le premier truc. Alors la clé secrète, généralement, on va dire, aujourd'hui, on ne va pas démontrer qu'on arrive à le faire. En réalité, quand vous utilisez du TLS, du SSH, ce genre de choses. Vous êtes sûrs de l'asymétrie. Qu'en fait c'est l' asymétrie qui est utilisée pour transmettre la clé, qui, elle, va servir ensuite à faire un chiffrement symétrique. Vous le savez tous, que l'asymétrique, il n'est utilisé que dans les premières parties de négoce, où on négocie une clé secrète, et ensuite cette clé secrète qui est échangée entre les deux parties, sur un canal clair avec de l'asymétrique, elle va être utilisée pour faire du chiffrement symétrique des deux côtés, ok ? Bon, on va imaginer qu'on arrive à se la passer la clé, de manière secrète.

C'est quoi le mot de passe du wifi, on va voir que le wifi, ça fonctionne exactement comme ça.

Enfin, tout fonctionne comme ça.

On arrive à se passer la clé secrètement, et puis, c'est bon, ok ? On va supposer que c'est bon.

Et dans tous les cas, avec l'asymétrique, on y arrive.

Alors la taille de la clé doit être supérieure ou égale à la taille de ce qu'on veut chiffrer.

Là c'est déjà plus compliqué, ça fait que si je veux chiffrer 25 méga de données, il me faudra une clé qui fasse 25 méga de long. C'est à dire beaucoup beaucoup de milliards de caractères.

OK ? Quand on a une clé wifi, généralement assez longue, mais elle ne fait pas non plus des milliards de caractères, et pourtant avec, on va faire une session wifi qui va durer 12 ou 24h donc on va chiffrer des milliards d'octets avec. Et pourtant, elle est de taille finie.

Donc comment est-ce qu'on fait pour, avec une clé qui est de taille finie, la rendre virtuellement infinie ? Pour ça, on utilise une solution qui s'appelle le Linear Feedback Shift Register, c'est à dire, en français, le "registre à décalage linéaire".

C'est un truc qu'on étudie en électronique, que j'ai étudié dans mes études d'ailleurs.

C'est la solution qui va faire en sorte qu'à partir de quelque chose qui est fixe, de taille fixe, on va pouvoir avoir quelque chose de taille infiniment grande. Mais comment ça fonctionne ? Comment ça fonctionne, on va voir ça.

Déjà, ce qu'il faut savoir, c'est que cette structure-là, on va le voir, elle est extrêmement légère, et donc elle peut tout à fait être chiffrée directement dans une puce électronique, OK ? C'est pas forcément dans un CPU.

donc, dans des choses, toutes petites, embarquées, on peut mettre du chiffrement grâce à cette structure-là.

Puisque c'est très petit dans les puces. Ca va consommer très peu d'énergie et ça va fonctionner à merveille.

Alors on va voir comment ça fonctionne. C'est pas très difficile comme ça fonctionne.

Au lieu de dire qu'on a une clé qui fait 32 octets ou 32 caractères, c'est un peu long à représenter 32 octets, puisqu'un octet fait 8 bits, donc si je veux représenter 32 octets, ça va être assez gros. Donc là, j'ai représenté 1 octet.

C'est à dire un caractère de ma clé. Donc, par exemple, si ma clé, c'est "foobar", ici, je représente le "f".

Et puis, il faut s'imaginer qu'il y a le "o", le "o", le "b" qui sont collés là. C'est trop large pour le slide.

Donc voilà un octet qui fait donc 8 bits, donc 256 possibilités à l'intérieur, OK ? Et en fait, le LFSR, qu'est-ce qu'il fait ? Il dit on prend cet octet, et puis on va décaler vers la droite, d'accord, les bits qui sont à l'intérieur, à chaque tour d'horloge.

Tout simplement. Et le bit qui va sortir de côté, on va l'utiliser pour faire 1 XOR avec un bit du clair. Et du coup en faisant tourner, j'ai une suite infinie de bits, donc, j'ai une suite infini d'octets.

Donc le premier état, c'est l'état numéro 1, puis je décale vers la droite, j'ai l'état numéro 2, etc.

et le bit qui sort, je le réinjecte à gauche.

Et donc en faisant tourner, j'ai une suite infinie, de bits donc, des octets bout à bout, on va faire une suite infinie d'octets si on les prend 8 par 8.

Alors attention, la somme est infinie mais elle n'est pas aléatoire.

C'est à dire que ça va se répéter, le cycle. Pourquoi ? Parce qu'on a rebranché tout bêtement.

On a dit la sortie, on la rebranche sur l'entrée, et puis ça tourne, OK ? Donc là, on a solutionné le fait qu'à partir d'un octet tout petit, en faisant tourner les bits qu'il y a dedans, et bien finalement, je vais pouvoir générer des bits et des bits et des bits, des octets, des octets, des octets. Si je prends par rapport à des octets, OK ? Donc, j'ai solutionné la deuxième problématique.

Cependant, vu que ça boucle, ce n'est pas vraiment "random" et c'est pas vraiment "never reused".

Donc, comment est-ce qu'on fait à partir de ce schéma-là pour ajouter de l'aléatoire dans ce qui va sortir ? C'est à dire que là c'est prévisible.

On est bien d'accord que tous les huit états, on va retrouver, tous les huit tours d'horloge, on va retrouver le même état dans le registre.

Et donc, on va réutiliser la même clé pour chiffrer du clair et donc ça ne va pas aller.

Alors comment est-ce qu'on fait pour complexifier ça ? On se pose un peu notre question, électronique, un peu mathématique aussi, ça va arriver. Et on se dit "Tiens, on va ajouter un petit peu de complexité sur la fonction de rétroaction." C'est à dire que plutôt que de faire re-rentrer mon bit de sortie directement à l'entrée, je vais aussi l'utiliser pour XORer les décalages.

OK...

Et là, ce qui va se passer, c'est que si je sors le 1 et que je le XORe avec ce qui est repoussé, etc, etc, etc.

Ca commence à devenir très sérieusement aléatoire ce qui sort.

C'est à dire que le registre, au fur et à mesure, qu'on va le décaler, il va être mélangé avec les bits qui sortent, et du coup, si je prends l'état de l'entier qui est à l'intérieur, donc qui va être situé forcément, puisqu'il y a qu'un octet entre 0 et 255.

Le premier entier, c'est 167, ensuite 83, ensuite 145, ensuite 240. Ca commence à devenir très sérieusement aléatoire.

C'est la base de ce qu'on appelle les générateurs pseudo-aléatoires.

C'est exactement ça un générateur pseudo-aléatoire, c'est ça.

Tu fais tourner, tu sors l'octet, tu fais tourner, tu sors l'octet, tu fais tourner et tu sors l'octet.

Ca peut être modélisé mathématiquement en un polynôme de degré n, n étant le nombre de bits qu'on veut utiliser. Et à chaque fois qu'on a une rétroaction, c'est à dire, qu'à chaque fois, que le bit de sortie re-rentre sur un des bits d'entrée, on utilise une puissance de x.

OK ? Et du coup on va se retrouver avec un peu de maths, mais qu'on ne verra pas aujourd'hui, qui disent qu'on peut solutionner ce polynôme, et donc, finalement, c'est pas mal, mais ça va se répéter quand même au bout d'un moment, OK ? C'est à dire que là, on est tous d'accord, que on va avoir de l'aléatoire, ça ressemble, et tout d'un coup, ça va quand même reboucler. Tout d'un coup, on va retrouver les mêmes valeurs qu'on avait à l'origine.

On a toujours un état, un ensemble d'états finis.

Et il y a un théorème mathématique, qu'on va voir, qui dit que selon les bits qu'on choisit pour faire la rétroaction, on peut faire en sorte qu'il y ait un maximum d'états aléatoires. Le maximum étant 2 puissance n-1, n étant le nombre de bits qui est à l'intérieur.

Donc là, si j'ai 8 bits, et que je fais 2 puissance n-1, je vais avoir une séquence maximum qui va être de 255 états différents.

OK.

Sauf que, pour que ça fonctionne, ce qu'on appelle une m-séquence, il faut que le nombre de bits qui sont réinjectés à l'intérieur du de la machine à états qu'on a ici, il faut que ce nombre-là soit impair, et il faut que les facteurs des x soient premiers entre eux.

C'est tout, OK ? Donc si on regarde S=X^8+X^7+X^6+X^5+1.

Là, on a des facteurs, on est déjà sur quelque chose qui va être impair et on va avoir des facteurs qui vont tous être premiers entre eux. Donc, si je reboucle les bits 8, 7, 6, 5 sur 8. Je vais effectivement générer 255 états, c'est à dire le maximum.

Si j'en reboucle d'autres, par exemple, que le 8e, c'est à dire que le dernier.

A ce moment-là, ça ne fonctionne pas parce que je suis sur quelque chose de pair, les facteurs ne sont pas premiers entre eux, donc, ça va reboucler, ça va se répéter avant les 255 états.

Tout simplement.

Donc, c'est plutôt pas mal ce truc-là, parce que là, je l'ai fait avec un octet, c'est à dire avec 8 bits.

Si je prend 32 bits, la période maximum avec les facteurs premiers en rebouclant bien comme il faut, en branchant bien mes XOR au bon endroit.

La période maximum, ça va être beaucoup.

4 milliards et des brouettes, 2^32 - 1, le nombre d'adresse IPv4 aujourd'hui. Bon, mais ça c'est autre chose. Et donc, du coup, avec juste 32 bits, c'est à dire 4 octets, en faisant tourner dans le registre, je vais pouvoir générer 4 milliards d'états différents et donc je vais pouvoir chiffrer 4 milliards de bits différents, c'est à dire 512 méga, donc, avec quatre octets d'une clé, en utilisant cette technique, je peux déjà chiffrer 512 mégaoctets de clair.

Ensuite, ça va se répéter. Et donc, si ça se répète, et bien ça invalide les conditions de Vernam, et donc le chiffrement n'est plus assuré.

Alors ça, c'est très simple à faire en C, en PHP, enfin, c'est des bits, c'est tout bête. D'accord ? C'est ce que traitent les CPU. Donc j'ai démontré ça en PHP, sur github.com/jpauli/PHP-Crypto Donc en fait, qu'est-ce que vous faites ? Alors moi j'ai pris 32 bits, OK ? Je me suis mis sur 4 octets, il n'y a pas tout le code parce que sinon, ça fait un peu beaucoup de choses.

Notamment la table des bits de rétroaction. Donc, si vous en avez 4, 5 ou 6, où sont les XOR ? Où est-ce qu'on les place ? Ca, c'est le fameux "Polynomial prime coefficient" où j'ai la grosse liste, qui va de 2 à 32, puisque je me suis arrêté à 32. Donc tout ça, je ne l'ai pas montré. En fait, c'est simplement, vous voulez mettre un bit à 1, vous faites un OR, OK ? Tout simplement.

Si vous voulez passer le bit à 0, vous faites un "Et non" (???) Je rappelle un petit peu comment ça fonctionne. Et puis ensuite, quand vous voulez ré-entrer, vous faites simplement un petit XOR avec les bits que vous avez, ce qu'on appelle des "taps", "Polynomial prime coefficient". Et du coup, avec un petit Yield, je me suis amusé avec.

OK ? Il n'y a pas tout, d'accord ? Et donc, du coup, tant que vous avez du clair, vous faites tourner votre registre et puis vous chiffrez avec.

Là, j'ai ré-implémenté le chiffrement symétrique, mais moi-même, à la main, plutôt que de dire "vas-y, chiffre".

Ce qui est fait derrière.

OK ? C'est plutôt assez simple.

J'initialise mon registre avec ma clé secrète. Donc, imaginons, plutôt que d'avoir mes 8 bits, donc mon octet, j'ai 4 octets, donc j'ai quatre caractères, donc, JULIEN, JULI, je les mets dans mon registre, et puis je fais tourner, et à chaque fois qu'il y a un bit qui sort de mon registre, je prends un bit de mon clair, je fais un XOR avec, et j'ai du chiffré. Et on appelle ça un "stream cipher", ça s'écrit avec un i.

Partout, j'ai essayé de chercher, je l'ai oublié celui-là.

Donc ça s'appelle le chiffrement par flux.

De stream cipher.

Il y a aussi le chiffrement par blocs, que je n'expliquerai pas. Donc, le chiffrement par flux, c'est simple, vous prenez une clé, vous initialisez votre LFSR, donc votre registre à décalage, et puis vous le faites tourner, toc toc, avec les bits de rétroaction qui changent l'état interne. Et chaque fois qu'il y a un bit qui sort, donc, à chaque top d'horloge, et bien vous chiffrez avec le clair.

Et du coup, vous avez du chiffré de l'autre côté. Et de l'autre côté, qu'est-ce qu'il fait ? Il prend la même clé, dans le même LFSR, il a donc les mêmes bits qui sortent, il refait son XOR, il a le clair.

Voilà, tout simplement.

Donc, ça, c'est ce qu'on appelle un registre à décalage et un stream cipher. Donc j'ai montré un petit peu pareil comment l'implémenter.

Donc ici, je récupère un octet aléatoire en utilisant ma fameuse LFSR donc mon fameux registre à décalage.

Donc, je le passe en paramètre, et puis je lui dis : "vas-y pour 0 à 8, puisque un octet, ça fait 8 bits, donc de 0 à 8, tourne, ajoute moi l'octet que tu décales, le bit, tac tac tac, tu me fabriques mon octet, tu me le retournes." "OK, je le retourne, sous forme d'un Hint." Alors là, PHP, il est pas super pour ça. Je préfère faire du C ou du Python. On en reparlera un petit peu après.

Et ensuite, ensuite, qu'est-ce que je fais ? Je chiffre.

C'est à dire que je prends le bit de sortie de mon registre à décalage et puis je le XOR, avec un des bits de mon entrée. Je fais ça au niveau octet plutôt. Et du coup, j'obtiens du chiffré et vous pouvez le lancer, aller sur github, le git-cloner, etc.

C'est PHP 7.1 minimum. Et ça fonctionne nickel. Vous mettez n'importe quel texte clair en entrée, vous prenez une clé, raisonnablement 8 ou 10 caractères. Et puis vous regardez la sortie, vous allez avoir un truc complètement incompréhensible, que vous remettez en entrée avec la même clé, vous retombez sur le clair.

Exactement. C'est le principe de base de la cryptographie en informatique, qui est exposé ici.

Alors, la clé n'est jamais réutilisée. On va voir que ça, c'est pas forcément simple non plus à utiliser.

Donc, les registres à décalage et les stream ciphers, donc le chiffrement par flux, finalement, c'est sécurisé, si jamais votre clé est secrète, si jamais les bits de rétroaction dans votre registre à décalage, sont secrets. C'est fermé.

Si la période de rétroaction est suffisamment grande, si c'est une m séquence, c'est à dire que si ça boucle en tout dernier lieu, que ça ne commence pas à boucler au bout de trois tours, parce que sinon ça sert à rien.

Et si jamais l'attaquant ne peut pas injecter de trafic en entrée.

Si l'attaquant peut injecter du trafic en entrée. A ce moment-là, le stream cipher peut se casser.

C'est à dire que si vous ne connaissez pas la clé et si vous ne connaissez pas les bits de rétroaction.

Vous mettez de l'entrée et vous regardez la sortie, il y a un théorème qui dit qu'en seulement 2n états, n étant la taille de la clé, vous pouvez récupérer la clé d'origine et les bits de rétroaction qu'il y avait à l'intérieur.

Il ne faut surtout pas avoir accès à l'entrée.

OK ? Donc du coup, en fait, on utilise notre clé pour initialiser tout simplement le registre à décalage.

Et alors, quand on utilise plusieurs fois la même clé, en fait, ce qu'on fait, c'est qu'on utilise ce qu'on appelle un vecteur d'initialisation.

Car on prend la clé et on la mélange, j'ai pas dit on la concatène, très mauvaise idée, on la mélange avec un vecteur d'initialisation qu'on suppose aléatoire. Un peu de problèmes de poule et d'oeuf là-dedans. Et du coup, on peut initialiser à chaque fois, avec la même clé, des états différents dans notre registre à décalage. Du coup, avec la même clé, si je mets avec un autre vecteur d'initialisation, la même clé va produire une sortie différente, puisque le vecteur d'initialisation va être différent.

Alors, il faut faire attention parce que si ça commence à boucler, et on sait qu'au bout de m, si on est sur une m-séquence, on sait que ça va boucler au bout d'un moment. Alors le moment peut être très long. Mais ça va boucler.

Et si jamais un attaquant peut injecter de l'entrée. A ce moment-là, il va pouvoir craquer mon registre à décalage. Donc, comment est-ce qu'on pourrait faire pour essayer de faire en sorte que ce registre à décalage soit encore plus puissant ? Qu'il puisse ne pas être craqué ? On va voir qu'en fait, on ne peut faire que repousser le temps.

Puisque la problématique d'origine, c'est qu'il me faut une clé à taille finie pour chiffrer un flux infini.

Si j'avais une taille de clé infinie, je n'aurais pas tous ces problèmes-là.

Mais je ne peux pas avoir une taille de clé infinie, on est obligé d'avoir une taille de clé finie.

32 caractères. Et je veux chiffrer 4 gigas, c'est-à-dire 32 caractères, enfin, 4 milliards de caractères. Donc, du coup, il faut que je trouve un moyen de mélanger tout ça grâce au LFSR, pour faire en sorte que ce soit le plus aléatoire possible. Alors ce qu'on peut faire, c'est qu'on peut se dire, "allez, je vais en brancher plusieurs ensemble." C'est super, enfin, la crypto, c'est génial.

C'est pas des maths, c'est des OU exclusifs.

Après, c'est des maths, pour trouver les m-séquences, c'est polynôme de Xième degré normalement.

On est censé savoir solutionner ça, avec Euler et toutes ses formules-là. Bon, bref.

Alors, on essaye de complexifier le truc mais...

comme on vient de le faire, c'est toujours linéaire, c'est à dire qu'on ne fait que pousser le moment où ça va se répéter.

On pousse la limite, on pousse la limite, on pousse la limite, en espérant qu'on ne puisse pas craquer l'état interne.

Alors, on va voir sur quoi ça a été utilisé tout ça. C'est assez rigolo. Et comment ça a été craqué.

C'est super sympa.

Les DVD.

Moi, je suis né en 82, donc, en 98-99, quand DECSS est sorti, je commençais.

J'étais en Terminal électronique, donc je câblais des microcontrôleurs, je faisais des portes logiques.

Et puis, quand j'ai vu DECSS, j'ai fait "Wow, Vous êtes bons !" Donc, DECSS, c'est quoi ? C'est exactement ce principe-là qui a été utilisé pour chiffrer les DVD.

Je parle bien de DVD, je ne parle pas de Blu-Ray, je ne parle pas de machins comme ça, OK ? Donc c'est comme ça que ça a été chiffré.

Et puisque je peux graver un DVD, et donc, je peux gérer les octets d'entrée en écoutant la sortie, avec suffisamment d'entrée et ben je peux craquer la boîte noire qui est dans les lecteurs DVD.

Elle est là.

il y avait 4 ou 5 registres à décalage à rétroaction, l'un sur l'autre.

Mais c'était linéaire. Et le fait que ce soit linéaire, ça s'est fait craquer.

Ca s'est fait craquer.

Vous avez tout le détail ici, qui est génial, qui date de 99, de la date où ça a été craqué. Tout ça, ça a été bien mis maintenant sur le web.

En fait, la problématique qui avait à l'origine c'est que le monde du libre, évidemment...

Vous chiffrez vos DVD, il faut avoir la clé, elle est dans le matériel, pour déchiffrer, elle est dans la puce matérielle.

Donc, quand on arrive sous Linux et qu'on met son DVD, dans son lecteur, je parle bien des platines de salon, les lecteurs de DVD, qu'on avait à l'époque dans les ordinateurs, n'ont pas de puce de décodage.

Donc, du coup, je prends mon fichier, je peux le lire parce que c'est dans le logiciel, mais je ne peux pas copier le fichier sur mon disque. Il va être copié et il va être encrypté avec le registre à décalage qui sont à l'intérieur. Et donc, du coup, le monde Linux en a eu marre et il a craqué tout ça. Et le code, il est depuis bien longtemps maintenant dans VLC.

Ca s'appelle libdvdcss. Et le code de craquage des clés qui prend aujourd'hui sur les puissances de nos machines. Je reviens à l'époque, c'était quoi que j'avais mis ? Ca prend très peu de temps. C'est où que j'ai j'écrit ça ? A l'époque, ça prenait 18 secondes pour craquer la clé avec un pentium III.

Aujourd'hui, vous mettez votre DVD, vous faites "copier", puis ça copie, et puis voilà, ça y est, c'est craqué.

On ne voit même plus.

On ne voit même plus la différence.

Donc, vous avez le code source qui est là. Donc, en C évidemment.

C'est le code source qui est implémenté dans VLC, donc, c'est un crack logiciel.

Parce que votre DVD, vous le mettez dans votre lecteur, et votre lecteur n'a pas la puce pour décoder. Donc du coup, il envoie le flux chiffré au logiciel, qui, lui, est censé avoir la clé.

A l'époque, WinDVD, c'est comme ça qu'on l'avait craqué aussi.

Ils avaient monté la clé, l'avait mise en mémoire non-chiffrée, donc, on a dumpé l'image de WinDVD puis on a trouvé la clé.

Ok, il y avait aussi ça qui était pas mal, bon...

Donc c'est pas mal ! Alors, on voit bien que les registres à décalage à rétroaction linéaire, on a beau les enchaîner les uns avec les autres, on ne fait que pousser l'échéance.

Et pousser l'échéance, c'est quoi ? C'est dépasser la taille de l'attaque par force brute.

Donc si on arrive à dépasser le temps qu'il faut pour attaquer par force brute.

C'est à dire force brute, tester toutes les possibilités de 0 à la dernière.

Ce qui peut prendre des secondes, des années, ça dépend de l'algo. Si on arrive à dire, on est force brute +4, et bien on a gagné.

Si on est force brute -2, on a perdu. Parce que le mec va l'utiliser pour craquer puisque ce sera plus rapide que la force brute.

Donc on appelle ça les attaques par corrélation, etc.

Alors en fait pour faire en sorte, c'est facile, que ces registres à décalage soient sécurisés entre guillemets, C'est à dire ne soit pas prévisibles, ne se répètent jamais, etc.

Ce qu'il faut, c'est utiliser de la réentrance qui ne soit pas linéaire.

Et là, ça va se compliquer un peu...

Voilà Trivium.

Trivium, c'est absolument extraordinaire.

Donc, pour ceux qui ne savent pas, ça c'est du ET logique, ça c'est du XOR.

Du XOR, du XOR et puis à la fin du XOR, voilà, vous avez votre bit de sortie.

Donc qu'est-ce qu'il y a là-dedans ? il y a trois registres à décalage : A, B et C.

A, il fait 93 digits, 93 bits.

B, il fait 84 bits et C fait 111.

Et on voit bien que l'entrée de 1 dépend en partie de la sortie de l'autre, ou pas d'ailleurs, ça dépend comment c'est fait.

Parce qu'il y a des 66 et 69 en fait là. Ici, un petit machin dessus, ça veut dire qu'ils sont...

qu'ils peuvent être swapés, ou ils peuvent partir dans d'autres trucs qui rebouclent. On peut essayer de complexifier au maximum.

Alors, sans rentrer dans les détails mathématiques, ce truc-là, il a une période de 2 puissance 64, ce qui est fondamentalement énorme aujourd'hui.

C'est à dire que, quand il est bien réglé, il va se répéter au bout de 2 puissance 64 états.

Faut y aller, hein, d'accord ?! C'est énorme. Et en plus, vous avez un End en sortie, un ET logique, et donc, le ET logique, c'est une multiplication modulo 2.

Ce qui fait que, cette fois-ci, quand on ajoute des multiplications par rapport aux additions, le temps n'est plus linéaire pour craquer ça, il part en exponentiel.

Ceux qui se souviennent, Donc, dès que vous ajoutez de la multiplication, ça part en exposant au niveau du temps qu'il faut pour pouvoir craquer ça.

Donc, comment ça marche ? Rapidement, vous mettez votre vecteur d'initialisation dans A, dans les digits de gauche, vous mettez votre clé secrète dans B, tout le reste est à 0. Vous faites tourner 1152, mathématicien, 1152 fois, et à la 1153e fois, vous avez votre bit de sortie. C'est parti, et avec ça vous pouvez XORer.

Alors là, vous allez en avoir 2 puissance 64, et, malgré le fait qu'on puisse gérer du clair en entrée, on ne pourra pas prévoir la sortie.

Puisque ce n'est pas linéaire, et qu'on a un ET logique sur la sortie. Et aujourd'hui, Trivium, c'est ce qui fonctionne.

On a trouvé des algos pour le craquer, alors je vous laisse relire les papers en PDF, à tête bien reposée.

On a réussi à le craquer en 2 puissance 68 temps, donc, c'est au-dessus de la force brute. Donc, aujourd'hui, c'est recommandé d'utiliser du trivium, comme stream cipher.

C'est d'ailleurs ce qui est utilisé dans TLS, etc, etc.

Mettez à jour vos TLS, 1.2, 1.3, d'accord ? Parce qu'avant, c'était du RC4, maintenant, c'est du Trivium. C'est quand même beaucoup mieux.

Alors un autre, j'en présente encore deux autres et c'est fini. Donc, A5/1, hum...

Une fois de plus, ce n'est pas compliqué. Le +, c'est un XOR, et ensuite il y a un ET logique entre plusieurs sorties et un clock en plus. Donc, on essaye de complexifier les choses.

Alors A5/1, qui est-ce qui connaît A5/1 ? A5/1, c'est plutôt assez intéressant. Donc, on a trois registres, pareil, 3 LFSR, on voit bien, empilées les unes avec les autres. Donc, 19, 22 et 23 digits.

Des bits, vous représentez des octets quand on les groupe par huit, je rappelle, ok ? Et là, on a encore un truc qui est non-linéaire puisqu'on a une majority function qui dit que, si tu es dans la majority function, tu te décales, sinon, tu ne te décales pas.

Donc, ça ne décale pas tout le temps. Et donc, du coup, la sortie est aussi imprévisible.

A5/1, c'était utilisé à l'époque, ça l'est toujours d'ailleurs, enfin plus trop d'ailleurs maintenant, bon, pour chiffrer le GSM, je parle bien du GSM, la 2G, d'accord ? Et ça a pris dix ans pour le casser, mais aujourd'hui, on peut considérer qu'il est cassé le A5/1.

Il y avait d'ailleurs des problèmes dans le protocole GSM qui ont affaibli beaucoup A5/1.

Donc, il ne faut plus utiliser A5/1. Aujourd'hui, si on veut faire quelque chose de vraiment cryptographiquement sûr.

Donc c'est un stream cipher qu'on utilisait avant, mais qu'on n'utilise plus trop.

RC4 tout le monde le connait celui-là. Il est génial.

Alors, il est cassé et tout, on va le voir mais il est génial.

Implémentez-le en C ou en PHP, vous verrez, c'est super à faire. Moi, je me suis éclaté quand je l'ai fait.

Donc, Rivest Cipher 4, ce qui est bien avec RC4, c'est que ça vient de...

alors, je ne sais plus, il faut regarder.

C'est Bell Laboratories, ou je ne sais plus. Et ça n'a jamais été publié, la source n'a jamais été publiée.

C'était proprio, d'accord ? Et ça a pris des années, et des années, et des années, avant de pouvoir le craquer.

Donc, c'est basé sur des octets et non plus des bits.

De toute façon, quand on en a 8, on a un octet, mais bon, voilà. En gros, vous prenez un tableau de 256 octets, et puis, vous mélangez les octets à l'intérieur, et puis, vous en prenez 2, aléatoirement, vous faites un XOR entre les deux, et ça, c'est votre octet, qui va vous servir à chiffrer un octet de clair. Donc, on a une grosse période, 10 puissance 100, c'est énorme.

OK ? Théoriquement, la période maximum, c'est à dire au bout de 2 puissance 170000, il va se répéter.

Vous voyez, les gars, vous pouvez en chiffrer des DVD de 4 gigas ou des Blu-Ray de 40 gigas avec ça.

Ca fait beaucoup.

Donc, on met ses 256 octets, on mélange, ok, on mélange des index I et J, c'est vachement bien foutu.

Et on sort. Donc, ça représente un truc comme ça, la vraie image. On sort 2 octets du tableau et ensuite on re-mélange. Donc là, c'est pareil, si vous voulez voir une petite démonstration de ça, fait en PHP, alors là, je n'ai pas sorti le code source.

Et je l'ai fait aussi en C, et celui-là, pour le coup, dans une extension PHP.

Donc, vous mettez l'extension, et puis, c'est fait en C derrière, donc je l 'ai implémenté pour vous montrer comment ça marche.

Il y a très peu de lignes de code finalement.

Bon après, c'est une classe, donc, du coup, pour mettre ça dans les slides, et que ce soit présentable, c'est un peu difficile.

Mais il n'y a pas beaucoup de lignes de code, si vous regardez bien. Alors ça a été cassé, ok ? Pour tout un tas de raisons.

Donc, en fait, souvent, le fait que les gens utilisaient un vecteur d'initialisation et le concatènaient avec la clé pour initialiser les 256 cases du tableau. Et, du coup, ça a mené à tout un tas de choses qui font que ça a été cassé.

Aujourd'hui donc, il ne faut plus l'utiliser. Et puis, vous savez dans quoi ça a été utilisé RC4 et comment ça a été cassé ? Dans WEP ! Vous souvenez de WEP qui a été craqué et qui, aujourd'hui, en 4 secondes, on casse la clé WEP.

Pourquoi on casse la clé WEP ? Parce que WEP a plein de problèmes, et parce qu'on utilise du RC4 avec une clé qui est microscopique. C'est du 56 octets minimum, enfin, vous pouvez faire du 64 ou 128.

Derrière, la checksum est linéaire.

C'est du CRC-32, donc ça chiffre rien. C'est linéaire, donc, ça se craque en un temps linéaire. Bref, voilà.

RC4 est sorti de TLS maintenant. Vous savez que si vous faites du TLS/SSL avec du RC4, vous allez avoir un truc rouge, une note rouge qui va vous dire "Ca ne va pas, tu utilises du RC4 dans ton chiffrement HTTPS, Ca va pas du tout, c'est craqué." Alors, qu'est-ce qu'on peut conclure ? On peut conclure que, finalement, on n'a parlé que des stream ciphers, c'est à dire du chiffrement par flux, et non pas du chiffrement par blocs, qui est utilisé par HMAC, notamment. Je vous laisserai regarder, c'est super intéressant aussi.

Donc les block ciphers, vous avez DES, AES, blowfish, tout ça, on en a pas parlé.

Donc chaque chiffreur, chaque cipher, chiffrement par flux, n'est pas forcément 100% cryptographiquement sûr.

Mais si vous arrivez à avoir une période qui est énorme, pour ne pas que ça se répète, pour que la clé, la taille de la clé, ne soit pas dépendante de la taille de ce qu'on veut en clair. Et si vous faites du XOR modulo 2 et que de l'autre côté, il a la même clé évidemment, pour faire son XOR et récupérer son clair.

A ce moment là, c'est la seule manière qui est mathématiquement sûre de chiffrer.

Et donc du coup, on utilise, nous, des compromis pour faire en sorte qu'une clé de taille fixe puisse être étendue à l'infini. Ces compromis, on les a vu un petit peu.

On a vu que la cryptanalyse fait que c'est grand, c'est grand, c'est grand, mais ce n'est pas infini. Donc, ça peut se casser, et donc, ça se casse et donc on en réinvente d'autres.

Renseignez-vous sur DJB, si vous ne connaissez pas, pour la crypto, voilà.

En gros, vous avez compris le principe, c'est vraiment très simple.

C'est XOR, c'est du AND, c'est du OR et c'est du décalage de bits.

Pas fondamentalement compliqué quand même.

Après, pour craquer tout ça, on part dans des mathématiques qui sont assez imbuvables, mais sinon vous avez vu que, électroniquement et au niveau informatique, c'est très simple.

Voilà, voilà ce qu'on pouvait dire.