Aller au contenu principal

Cryptographie : coder, chiffrer, signer

Ce que ce chapitre apporte6 points
  • Distinguer coder, chiffrer et hacher, et dire ce que chacun garantit.
  • Casser un chiffrement mono-alphabétique par analyse de fréquence, et dire pourquoi la taille de l'espace des clés n'y change rien.
  • Énoncer le principe de Kerckhoffs et ce qu'il interdit.
  • Opposer chiffrement symétrique et asymétrique, et dire ce que chacun coûte.
  • Dérouler RSA de bout en bout, et expliquer par quel théorème le déchiffrement retombe sur le message.
  • Choisir l'outil qui assure la confidentialité, l'authentification ou l'intégrité, et ne pas les confondre.

L'arithmétique modulaire du chapitre précédent n'a pas été construite pour elle-même. Elle sert, et elle sert à une chose précise : rendre facile dans un sens ce qui est impraticable dans l'autre. Multiplier deux nombres premiers de trois cents chiffres prend une microseconde ; retrouver ces deux facteurs à partir du produit n'est fait par personne.

Ce chapitre installe cette asymétrie et ce qu'elle permet. Il commence par séparer trois mots que l'usage confond, montre pourquoi un chiffrement qui paraît solide tombe en dix minutes, puis déroule RSA de bout en bout sur de petits nombres.

Coder, chiffrer, hacher

L'outillage arithmétique est complet : il peut maintenant servir. Avant d'en faire un système de chiffrement, il faut lever une confusion de vocabulaire qui fausse ensuite tous les raisonnements de sécurité. Trois mots qu'on confond, trois opérations différentes.

Les distinguer

Coder (ou encoder) : représenter une information dans un autre alphabet. ASCII, UTF-8, base64. Réversible, sans secret, ce n'est pas de la sécurité.

Chiffrer : rendre une information incompréhensible sans la clé. Réversible avec la clé. (« Crypter » n'existe pas en français ; « décrypter » si, c'est lire sans la clé, donc casser.)

Hacher : produire une empreinte de taille fixe. Irréversible, et sans clé. Sert à l'intégrité et au stockage des mots de passe.

Chiffrement mono-alphabétique

Chaque symbole est remplacé par un autre, toujours le même. Le chiffre de César est le cas le plus simple : un décalage constant.

Le premier parchemin

Le message chiffré est 9153787770964, décalé de K=4K = 4. On applique le décalage inverse, chiffre par chiffre :

chiffre clair=(chiffre chiffreˊ4)mod10\text{chiffre clair} = (\text{chiffre chiffré} - 4) \bmod 10

959 \to 5, 171 \to 7 (car 14=37[10]1 - 4 = -3 \equiv 7 [10]), 515 \to 1, 393 \to 9, 737 \to 3, 848 \to 4

On obtient 5719343336520, treize chiffres qu'on regroupe au format de coordonnées : 57°19'34.3"N, 3°36'52.0"W, quelque part dans les Highlands.

Compter les chiffres avant de découper

Le format visé consomme 2+2+2+12 + 2 + 2 + 1 chiffres pour la latitude (degrés, minutes, secondes, dixième) et 1+2+2+11 + 2 + 2 + 1 pour la longitude, soit treize exactement. Si le message chiffré n'en a que douze, c'est qu'un chiffre s'est perdu à la recopie, et aucun découpage ne tombera juste. Vérifier la longueur attendue avant de déchiffrer évite de chercher l'erreur dans le mauvais endroit.

main.py
Sortie
>_ Prêt à exécuter…
Pourquoi ce chiffrement ne vaut rien

L'espace des clés compte dix possibilités. Les essayer toutes prend une microseconde. Et sur du texte, même un alphabet de substitution quelconque, fort de 26!26! clés, soit plus de 4×10264 \times 10^{26}, tombe en quelques secondes : il préserve les fréquences.

L'analyse de fréquence

En français, le ee représente environ 15 % des lettres, loin devant tous les autres. Un chiffrement mono-alphabétique déplace cette signature sans la détruire : la lettre la plus fréquente du texte chiffré est presque sûrement un ee chiffré.

main.py
Sortie
>_ Prêt à exécuter…

Le chiffre de Vigenère répond à cette attaque en utilisant plusieurs alphabets, pilotés par un mot-clé : une même lettre claire devient des lettres chiffrées différentes selon sa position. Les fréquences sont lissées, mais l'attaque de Kasiski retrouve la longueur de la clé en repérant les motifs répétés, et ramène le problème à autant de chiffres de César.

Symétrique et asymétrique

Deux familles

Symétrique : la même clé chiffre et déchiffre. Rapide, adapté aux gros volumes. Standard actuel : AES. Problème : il faut avoir transmis la clé au préalable, par un canal sûr.

Asymétrique : deux clés liées mathématiquement. La clé publique chiffre et se diffuse à tous ; la clé privée déchiffre et ne quitte jamais son propriétaire. Standard historique : RSA. Lent, mais résout le problème de l'échange de clé.

En pratique, les deux ensemble

Une connexion HTTPS commence par de l'asymétrique pour convenir d'une clé de session, puis bascule en symétrique pour toute la suite. On paie le coût du chiffrement lent une seule fois, au début, et l'on obtient la rapidité d'AES avec la souplesse de RSA. C'est la réponse à « comment envoyer un message confidentiel sans avoir échangé de code secret au préalable ».

Le principe de Kerckhoffs

La sécurité d'un système ne doit reposer que sur le secret de la clé, jamais sur celui de l'algorithme. AES et RSA sont entièrement publics, spécifiés, et attaqués par la communauté depuis des décennies, c'est ce qui fonde la confiance qu'on leur accorde. Un algorithme secret est un algorithme que personne n'a pu casser publiquement, ce qui n'est pas la même chose.

RSA, pas à pas

L'algorithme complet

Génération des clés

  1. Choisir deux grands premiers PP et QQ, et poser N=PQN = PQ.
  2. Calculer φ(N)=(P1)(Q1)\varphi (N) = (P - 1)(Q - 1).
  3. Choisir EE premier avec φ(N)\varphi (N).
  4. Calculer D=E1modφ(N)D = E^{-1} \operatorname{mod} \varphi (N) par Euclide étendu.

Clé publique : (N,E)(N, E). Clé privée : (N,D)(N, D). On détruit PP, QQ et φ(N)\varphi (N).

Chiffrement : C=MEmodNC = M^E \operatorname{mod} N Déchiffrement : M=CDmodNM = C^D \operatorname{mod} N

Les deux dernières lignes se lisent à voix haute : le chiffré est le message élevé à la puissance EE, modulo NN ; le message est le chiffré élevé à la puissance DD, modulo NN. C'est la même opération dans les deux sens, avec deux exposants différents, et c'est l'exponentiation modulaire rapide de la section précédente qui l'exécute.

Générer la clé jouet, étape par étape

1. Deux premiers. P=61P = 61 et Q=53Q = 53, d'où N=61×53=3233N = 61 \times 53 = 3233. C'est ce seul nombre, 32333233, qui sera publié : 6161 et 5353 ne doivent plus jamais apparaître nulle part.

2. L'indicatrice. φ(3233)=(611)(531)=60×52=3120\varphi(3233) = (61 - 1)(53 - 1) = 60 \times 52 = 3120. Le calcul est immédiat parce qu'on connaît la factorisation ; sans elle il faudrait la retrouver, et c'est précisément ce qui est hors de portée sur de vrais nombres.

3. L'exposant public. E=17E = 17. Il faut le vérifier premier avec 31203120, et la descente d'Euclide de tout à l'heure l'a déjà fait : le pgcd valait 1.

4. L'exposant privé. D=171mod3120D = 17^{-1} \bmod 3120, soit exactement l'inverse calculé plus haut à la main : D=2753D = 2753. Contrôle : 17×2753=46801=15×3120+117 \times 2753 = 46801 = 15 \times 3120 + 1, donc bien 1 [3120]\equiv 1 \ [3120].

Clé publique (3233;17)(3233 ; 17), clé privée (3233;2753)(3233 ; 2753). On détruit 6161, 5353 et 31203120.

Un tour complet sur un message. Avec M=65M = 65 : le chiffré vaut 6517mod3233=279065^{17} \bmod 3233 = 2790, et le déchiffré 27902753mod3233=652790^{2753} \bmod 3233 = 65. Les deux exposants sont énormes, mais l'exponentiation modulaire rapide les traite en une poignée d'opérations.

La figure ci-dessous déroule ces quatre étapes. Cliquer sur chacune montre à quoi elle sert et, surtout, ce que devient sa valeur : publiée, gardée, ou détruite. C'est cette répartition qui fait toute la sécurité, et elle disparaît dans une liste à puces.

message65^17 mod 3233clé publiquechiffré2790^2753 mod 3233clé privéedéchiffré65

Les deux exposants sont énormes et pourtant instantanés : l'exponentiation rapide remplace 17 multiplications par 4 mises au carré.

Ce qui circule : N = 3233 et E = 17. Pour en tirer D, il faut φ(N) ; pour φ(N), il faut P et Q ; pour P et Q, il faut factoriser N.

Ici, 56 divisions suffisent, un ordinateur les fait en une fraction de seconde. Sur une clé réelle, N compte 600 chiffres et c'est cette seule étape qui devient impossible : toutes les autres restent aussi rapides qu'ici.

La clé jouet du cours, étape par étape. Modifier P, Q ou E permet de casser la clé exprès : essayer E = 15, qui n'est pas premier avec 3120, pour voir la génération s'arrêter à la troisième étape.

Trois choses se lisent sur cette figure, et chacune se retient mieux qu'une phrase de conclusion.

  • φ(N)\varphi(N) est détruit. C'est la seule des cinq valeurs à ne finir ni dans la clé publique ni dans la privée. Elle est pourtant celle qui les relie : qui la connaît calcule DD en une ligne.
  • EE doit être premier avec φ(N)\varphi(N), sinon il n'a pas d'inverse et la quatrième étape n'a rien à calculer. Ce n'est pas une précaution, c'est une condition d'existence.
  • L'aller-retour referme la boucle parce que ED1 [φ(N)]ED \equiv 1 \ [\varphi(N)], et pour aucune autre raison. Changer DD d'une unité suffit à ne plus rien retrouver.
Ces nombres sont bien trop petits

Un NN de quatre chiffres se factorise de tête, ou presque : il suffit de tester les premiers jusqu'à 323357\sqrt{3233} \approx 57, soit seize divisions. La clé jouet sert à voir le mécanisme, jamais à protéger quoi que ce soit.

Une clé réelle emploie PP et QQ d'environ 300 chiffres chacun, pour un NN de 600 chiffres. Toutes les étapes ci-dessus restent les mêmes, et s'exécutent encore en une fraction de seconde : c'est la seule étape absente, la factorisation, qui devient hors de portée.

Pourquoi ça marche

Par construction ED1 [φ(N)]ED \equiv 1 \ [\varphi(N)], donc ED=1+kφ(N)ED = 1 + k\varphi(N) pour un entier kk. Alors :

CD=(ME)D=MED=M1+kφ(N)=M×(Mφ(N))kC^D = (M^E)^D = M^{ED} = M^{1 + k\varphi(N)} = M \times \left(M^{\varphi(N)}\right)^k

Et le théorème d'Euler donne Mφ(N)1 [N]M^{\varphi(N)} \equiv 1 \ [N], d'où CDM×1kM [N]C^D \equiv M \times 1^k \equiv M \ [N]. ∎

Le théorème d'Euler suppose MM premier avec NN, c'est-à-dire non multiple de PP ni de QQ. C'est le cas de presque tous les messages, et le cas restant fonctionne aussi, par un raisonnement séparé modulo PP puis modulo QQ.

Trois lignes, et tout le chapitre y passe : la division euclidienne pour obtenir DD, les congruences pour réduire, l'indicatrice d'Euler pour faire disparaître le facteur parasite. Rien n'y est superflu, et retirer une seule des quatre étapes de la génération casse la démonstration.

Où est le secret

Tout le monde connaît NN et EE. Pour trouver DD, il faut φ(N)\varphi(N) ; pour φ(N)\varphi(N), il faut PP et QQ ; pour PP et QQ, il faut factoriser NN. Toute la sécurité de RSA tient à ce dernier maillon, et à rien d'autre.

Le second parchemin

Un message a été intercepté : une liste de blocs chiffrés avec la clé publique jouet N=3233N = 3233, E=17E = 17. Le programme ci-dessous mène l'attaque de bout en bout : factoriser NN, en déduire DD, déchiffrer.

main.py
Sortie
>_ Prêt à exécuter…
Ce RSA-là est cassé, et pour une raison instructive

Chiffrer caractère par caractère avec la même clé donne toujours le même bloc pour le même caractère. Dans la liste ci-dessus, 1992 apparaît sept fois : c'est l'espace, et le message clair compte exactement sept espaces. On vient donc de reconstruire, sans le vouloir, un chiffrement mono-alphabétique, cassable par analyse de fréquence sans jamais factoriser NN.

Le vrai RSA chiffre des blocs de la taille de NN (2048 bits) et ajoute un remplissage aléatoire (OAEP) : deux chiffrements du même message donnent alors deux résultats différents. Sans remplissage, RSA est déterministe, donc faible : un algorithme correct mal employé ne protège rien.

Vérification rapideon peut se reprendre

1.Sur quoi repose la sécurité de RSA ?

2.Chiffrer avec la clé publique du destinataire assure…

3.Pourquoi calcule-t-on les puissances par exponentiation rapide ?

4.Que devient φ(N) une fois la clé générée ?

5.Hacher un message assure…

Confidentialité, authentification, intégrité

Chiffrer ne répond qu'à une question sur trois.

Trois propriétés distinctes

Confidentialité : personne d'autre ne peut lire. Chiffrer avec la clé publique du destinataire : lui seul possède la privée qui déchiffre.

Authentification : le destinataire sait qui a écrit. C'est la signature : l'expéditeur applique sa clé privée à l'empreinte du message ; n'importe qui vérifie avec sa clé publique. Les deux usages sont symétriques, et c'est la même mécanique employée dans l'autre sens.

Intégrité : le message n'a pas été modifié. C'est le rôle du hachage : on transmet l'empreinte, le destinataire la recalcule et compare.

Les deux premières se confondent tant qu'on n'a pas vu quelle clé sert à quoi, et dans quel sens. Les deux schémas ci-dessous se lisent en trois secondes et règlent la question.

Pour la confidentialité, Alice chiffre avec la clé publique de Bob. Elle est publique : n'importe qui peut donc écrire à Bob, ce qui est voulu. Seul Bob possède la privée correspondante, donc lui seul peut lire.

Diagramme de séquence
AliceBobchiffre(message, clé publique de Bob)message chiffréinterceptable, mais illisibledéchiffre(clé privée de Bob)

Ce qu'il faut regarder sur ce schéma : à qui appartiennent les deux clés citées. Les deux sont à Bob. Alice ne détient aucun secret, et pourtant elle chiffre : c'est là toute la nouveauté de l'asymétrique. Seule la flèche du milieu traverse le réseau, et ce qu'elle transporte ne se lit pas sans la clé privée, qui n'a jamais circulé.

Pour l'authentification, tout s'inverse. Alice signe avec sa propre clé privée, que personne d'autre ne possède. N'importe qui vérifie avec sa clé publique, et cette vérification prouve que le message vient bien d'elle.

Diagramme de séquence
AliceBobempreinte = hache(message)signature = chiffre(empreinte, clé privée d'Alice)message + signaturedéchiffre(signature, clé publique d'Alice)recalcule l'empreinte et comparesignature valide, c'est bien elle

Même lecture, et la comparaison des deux schémas donne la règle : ici, les deux clés citées appartiennent à Alice, l'expéditrice. Le message lui-même circule en clair ; ce qui est chiffré, c'est son empreinte. Personne d'autre qu'Alice ne peut produire cette signature, mais tout le monde peut la vérifier, puisque la clé publique est publique.

La question qui tranche : à qui appartient la clé employée ?

Clé publique du destinataire : confidentialité. Beaucoup peuvent écrire, un seul peut lire.

Clé privée de l'expéditeur : authentification. Un seul peut écrire, beaucoup peuvent vérifier.

En pratique on fait les deux à la fois, en signant puis en chiffrant. Et l'on ne signe jamais le message entier, seulement son empreinte : c'est plus court, et cela apporte l'intégrité par la même opération.

L'intégrité, ailleurs qu'en cryptographie

Quatre exemples reposent tous sur une opération modulaire : la clé de contrôle du numéro de sécurité sociale, la dernière lettre d'un IBAN, le bit de parité d'une trame, les codes correcteurs d'erreurs. Tous servent à détecter une altération. Aucun ne protège contre un adversaire, seulement contre l'erreur de saisie ou de transmission. C'est de l'intégrité accidentelle, pas de l'intégrité cryptographique.

main.py
Sortie
>_ Prêt à exécuter…
Pourquoi les clés s'allongent

La sécurité se mesure en bits : une clé de kk bits offre 2k2^k possibilités, et chaque bit ajouté double le travail de l'attaquant. Une clé de 56 bits (l'ancien DES) est tombée par recherche exhaustive en moins d'une journée dès 1999 ; AES-256 est hors d'atteinte de toute attaque exhaustive concevable.

Pour RSA, ce n'est pas l'attaque exhaustive qui compte mais la factorisation : les progrès des algorithmes et du matériel ont fait passer la recommandation de 1024 à 2048, puis 3072 bits.

À calculer soi-même

RSA se comprend en le faisant tourner une fois sur de petits nombres. Toutes les étapes tiennent dans un bloc, et aucune ne demande autre chose qu'une division.

RSA sur de petits nombres

  • 1.

    Deux premiers valent 11 et 13. Combien vaut le module NN ?

  • 2.

    Combien vaut φ(N)\varphi(N) ?

  • 3.

    L'exposant public vaut 7 et l'exposant privé 103. Combien vaut leur produit modulo φ(N)\varphi(N) ?

  • 4.

    Un message vaut 5. Combien vaut le chiffré, c'est-à-dire 575^7 modulo 143 ?

  • 5.

    Une clé RSA de 2 048 bits a un module de combien de chiffres décimaux environ ?

  • 6.

    Combien de clés distinctes un chiffrement mono-alphabétique sur 26 lettres offre-t-il ?

La dernière réponse est celle qui trompe. Vingt-six factorielle dépasse quatre cents millions de milliards de milliards de clés, et ce chiffrement se casse pourtant en quelques minutes sur un texte d'une page. La taille de l'espace des clés ne mesure pas la solidité d'un chiffrement : elle ne mesure que le coût d'une recherche exhaustive, qui n'est pas l'attaque employée.

Où la démarche dérape

Un calcul de clé mené sans faute, sur une valeur de φ\varphi qui ne tient pas.

Un phi qu'on croit toujours égal à N moins un

Une seule étape est fausse. Désigner laquelle.

Un module RSA vaut N=3xN = 3x, produit des deux premiers 3 et xx. On cherche φ(N)\varphi(N), qui sert à calculer la clé privée.

Vérification

Vérification rapideon peut se reprendre

1.Quelle est la différence entre coder et chiffrer ?

2.Pourquoi un chiffrement mono-alphabétique tombe-t-il malgré ses 26 factorielle clés ?

3.Que dit le principe de Kerckhoffs ?

4.Pour signer un message, quelle clé l'expéditeur emploie-t-il ?

Exercices type

Pourquoi RSA ne se chiffre-t-il jamais nu ?

Parce qu'il est déterministe : un même message donne toujours le même chiffré. Un attaquant qui soupçonne le contenu peut donc le chiffrer lui-même avec la clé publique, qui est publique, et comparer.

Sur un message pris dans un petit ensemble, un montant, une réponse par oui ou non, une date, la comparaison suffit à tout révéler sans rien casser. Le remplissage aléatoire ajouté avant le chiffrement rompt ce déterminisme, et c'est pour cela qu'il n'est jamais facultatif.

Chiffrer avec la clé publique ou avec la clé privée : qu'est-ce que cela change ?

Tout, et les deux usages ne se remplacent pas.

Chiffrer avec la clé publique du destinataire assure la confidentialité : lui seul possède la clé privée qui défait l'opération.

Chiffrer avec sa propre clé privée assure l'authentification : tout le monde peut vérifier avec la clé publique correspondante, et lui seul a pu produire le résultat. Ce n'est pas un secret, c'est une preuve d'origine.

Pourquoi emploie-t-on un chiffrement symétrique alors que l'asymétrique suffirait ?

Pour une raison de coût. L'asymétrique est de plusieurs ordres de grandeur plus lent, parce qu'il repose sur des exponentiations modulaires sur des nombres de plusieurs centaines de chiffres.

Les protocoles réels emploient donc les deux : l'asymétrique pour transporter une clé de session tirée au hasard, le symétrique pour chiffrer les données avec cette clé. L'asymétrique résout le problème de l'échange de clé, et le symétrique fait le travail.

Un hachage protège-t-il la confidentialité ?

Non, et il n'est pas fait pour. Un hachage est irréversible et sans clé : il ne cache rien, puisqu'il ne peut pas être défait, y compris par celui qui devrait lire le message.

Ce qu'il garantit est l'intégrité : deux contenus différents donnent, en pratique, deux empreintes différentes. Comparer l'empreinte reçue à l'empreinte calculée dit si le contenu a été modifié, et rien d'autre.

Que se passe-t-il si les deux premiers PP et QQ sont trop proches l'un de l'autre ?

Le module devient factorisable rapidement. Si PP et QQ sont voisins, ils encadrent tous deux N\sqrt{N}, et il suffit d'essayer les entiers autour de cette racine pour retrouver le plus petit des deux.

C'est pourquoi une génération de clé sérieuse n'impose pas seulement que les deux facteurs soient premiers et grands : elle impose aussi qu'ils soient éloignés. La difficulté de la factorisation n'est pas une propriété de la taille seule.

La méthode

  1. Nommer la propriété visée avant de choisir un outil : confidentialité, authentification ou intégrité. Chacune appelle une opération différente, et les confondre produit un système qui ne protège rien de ce qu'on croyait.
  2. Pour RSA, dérouler les quatre étapes dans l'ordre : NN, puis φ(N)\varphi(N), puis l'exposant privé, puis le déchiffrement.
  3. Contrôler que E×D1(modφ(N))E \times D \equiv 1 \pmod{\varphi(N)} avant d'aller plus loin. Une erreur ici rend tout le reste faux sans qu'aucun calcul ne proteste.
  4. Réduire à chaque étape dans un calcul modulaire, et procéder par carrés successifs pour une puissance. Ne jamais développer une grande puissance.
  5. Vérifier par l'aller-retour : rechiffrer le message obtenu et comparer au chiffré de départ.
  6. Ne jamais employer RSA nu, ni conclure qu'un chiffrement est solide parce que son espace de clés est grand.

Synthèse

  • Coderchiffrerhacher : réversible sans clé, réversible avec la clé, irréversible et sans clé.
  • Un chiffrement mono-alphabétique tombe par l'analyse de fréquence, quelle que soit la taille de son espace de clés. La solidité ne se mesure pas au nombre de clés.
  • Kerckhoffs : la sécurité repose sur la clé, jamais sur le secret de l'algorithme.
  • Le symétrique est rapide et pose un problème d'échange de clé ; l'asymétrique résout l'échange et coûte cher. Les protocoles réels emploient les deux.
  • RSA : C=MEmodNC = M^E \bmod N et M=CDmodNM = C^D \bmod N, avec ED1(modφ(N))ED \equiv 1 \pmod{\varphi(N)}. C'est le théorème d'Euler qui fait retomber le déchiffrement sur le message.
  • RSA est déterministe, donc à ne jamais employer sans remplissage aléatoire.
  • Confidentialité : clé publique du destinataire. Authentification : clé privée de l'expéditeur. Intégrité : hachage.
  • Toute la sécurité tient à ce que calculer φ(N)\varphi(N) exige de factoriser NN, ce que personne ne sait faire vite.

Et ensuite

Le chiffrement protège contre un adversaire. Il ne protège contre rien d'autre, et surtout pas contre le bruit : un bit retourné par une ligne défaillante donne un déchiffrement faux sans que rien ne le signale. Codes correcteurs d'erreurs traite ce second problème avec la même arithmétique, et une intention opposée.

Mettre en pratique