Chiffrement de César et RSA
Chiffrement de César et RSA
Cryptographie
1. Le chiffrement de César
Voici une figure avec l’alphabet d’origine en haut et en rouge, en correspondance avec l’alphabet
pour le chiffrement en-dessous et en vert.
Nous adopterons la convention suivante, en vert c’est la partie du message à laquelle tout le
monde a accès (ou qui pourrait être intercepté), c’est donc le message crypté. Alors qu’en rouge
c’est la partie du message confidentiel, c’est le message en clair.
Pour prendre en compte aussi les dernières lettres de l’alphabet, il est plus judicieux de représenté
l’alphabet sur un anneau. Ce décalage est un décalage circulaire sur les lettres de l’alphabet.
1
2
Pour déchiffrer le message de César, il suffit de décaler les lettres dans l’autre sens, D se déchiffre
en A, E en B,...
Et la célèbre phrase de César est :
ALEA JACTA EST
qui traduite du latin donne « Les dés sont jetés ».
par
A 7−→ 0 B 7−→ 1 C 7−→ 2 ... Z 7−→ 25
1.3. Modulo
Soit n Ê 2 un entier fixé.
Définition 1
a ≡ b (mod n).
Pour nous n = 26. Ce qui fait que 28 ≡ 2 (mod 26), car 28 − 2 est bien divisible par 26. De même
85 = 3 × 26 + 7 donc 85 ≡ 7 (mod 26).
On note Z/26Z l’ensemble de tous les éléments de Z modulo 26. Cet ensemble peut par exemple
être représenté par les 26 éléments {0, 1, 2, . . . , 25}. En effet, puisqu’on compte modulo 26 :
0, 1, 2, . . . , 25, puis 26 ≡ 0, 27 ≡ 1, 28 ≡ 2, . . . , 52 ≡ 0, 53 ≡ 1, . . .
Plus généralement Z/nZ contient n éléments. Pour un entier a ∈ Z quelconque, son représentant
dans {0, 1, 2, . . . , n − 1} s’obtient comme le reste k de la division euclidienne de a par n : a = bn + k.
De sorte que a ≡ k (mod n) et 0 É k < n.
Ck
Z/26Z Z/26Z
Dk
4
Une autre façon de voir la fonction de déchiffrement est de remarquer que D k (x) = C −k (x). Par
exemple C −3 (x) = x + (−3) ≡ x + 23 (mod 26).
Voici le principe du chiffrement : Alice veut envoyer des messages secrets à Bruno. Ils se sont
d’abord mis d’accord sur une clé secrète k, par exemple k = 11. Alice veut envoyer le message
"COUCOU" à Bruno. Elle transforme "COUCOU" en "2 14 20 2 14 20". Elle applique la fonction
de chiffrement C 11 (x) = x + 11 à chacun des nombres : "13 25 5 13 25 5" ce qui correspond au mot
crypté "NZFNZF". Elle transmet le mot crypté à Bruno, qui selon le même principe applique la
fonction de déchiffrement D 11 (x) = x − 11.
ALICE BRUNO
Ck Dk
2 14 20 2 14 20 13 25 5 13 25 5 13 25 5 13 25 5 2 14 20 2 14 20
Exemple 1
C 13 (x) = x + 13
et comme −13 ≡ 13 (mod 26) alors D 13 (x) = x + 13. La fonction de déchiffrement est la même
que la fonction de chiffrement !
Exemple : déchiffrez le mot "PRFNE".
Notons ici deux points importants pour la suite : tout d’abord nous avons naturellement considéré
un mot comme une succession de lettres, et chaque opération de chiffrement et déchiffrement
s’effectue sur un bloc d’une seule lettre. Ensuite nous avons vu que chiffrer un message est une
opération mathématique (certes sur un ensemble un peu spécial).
Il est clair que ce chiffrement de César est d’une sécurité très faible. Si Alice envoie un message
secret à Bruno et que Chloé intercepte ce message, il sera facile pour Chloé de le décrypter même
si elle ne connaît pas la clé secrète k. L’attaque la plus simple pour Chloé est de tester ce que
donne chacune des 26 combinaisons possibles et de reconnaître parmi ces combinaisons laquelle
donne un message compréhensible.
1.6. Algorithmes
Les ordinateurs ont révolutionné la cryptographie et surtout le décryptage d’un message intercepté.
Nous montrons ici, à l’aide du langage Python comment programmer et attaquer le chiffrement de
César. Tout d’abord la fonction de chiffrement se programme en une seule ligne :
5
def cesar_chiffre_nb(x,k):
return (x+k)%26
Ici x est un nombre de {0, 1, . . . , 25} et k est le décalage. (x+k)%26 renvoie le reste modulo 26 de la
somme (x+k). Pour le décryptage, c’est aussi simple :
Algorithme . [Link] (2)
def cesar_dechiffre_nb(x,k):
return (x-k)%26
Pour chiffrer un mot ou un phrase, il n’y a pas de problèmes théoriques, mais seulement des
difficultés techniques :
– Un mot ou une phrase est une chaîne de caractères, qui en fait se comporte comme une liste.
Si mot est une chaîne alors mot[0] est la première lettre, mot[1] la deuxième lettre... et la
boucle for lettre in mot: permet de parcourir chacune des lettres.
– Pour transformer une lettre en un nombre, on utilise le code Ascii qui à chaque caractère
associe un nombre, ord(A) vaut 65, ord(B) vaut 66... Ainsi (ord(lettre) - 65) renvoie le
rang de la lettre entre 0 et 25 comme nous l’avons fixé dès le départ.
– La transformation inverse se fait par la fonction char : char(65) renvoie le caractère A,
char(66) renvoie B...
– Pour ajouter une lettre à une liste, faites [Link](lettre). Enfin pour transformer
une liste de caractères en une chaîne, faites "".join(maliste).
Ce qui donne :
Algorithme . [Link] (3)
def cesar_chiffre_mot(mot,k):
message_code = [] # Liste vide
for lettre in mot: # Pour chaque lettre
nb = ord(lettre)-65 # Lettre devient nb de 0 à 25
nb_crypte = cesar_chiffre(nb,k) # Chiffrement de César
lettre_crypte = chr(nb_crypte+65) # Retour aux lettres
message_code.append(lettre_crypte) # Ajoute lettre au message
message_code = "".join(message_code) # Revient à chaine caractères
return(message_code)
Pour l’attaque on parcourt l’intégralité de l’espace des clés : k varie de 0 à 25. Noter que pour
décrypter les messages on utilise ici simplement la fonction de César avec la clé − k.
6
def cesar_attaque(mot):
for k in range(26):
print(cesar_chiffre_mot(mot,-k))
return None
2. Le chiffrement de Vigenère
Nous avons vu que le chiffrement de César présente une sécurité très faible, la principale raison
est que l’espace des clés est trop petit : il y a seulement 26 clés possibles, et on peut attaquer un
message chiffré en testant toutes les clés à la main.
Au lieu de faire correspondre circulairement les lettres, on associe maintenant à chaque lettre une
autre lettre (sans ordre fixe ou règle générale).
Par exemple :
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
F Q B M X I T E P A L W H S D O Z K V G R C N Y J U
Avantage : nous allons voir que l’espace des clés est gigantesque et qu’il n’est plus question d’énu-
mérer toutes les possibilités.
Inconvénients : la clé à retenir est beaucoup plus longue, puisqu’il faut partager la clé consti-
tuée des 26 lettres "FQBMX...". Mais surtout, nous allons voir que finalement ce protocole de
chiffrement est assez simple à « craquer ».
Attaque statistique
La principale faiblesse du chiffrement mono-alphabétique est qu’une même lettre est toujours
chiffrée de la même façon. Par exemple, ici E devient X. Dans les textes longs, les lettres n’ap-
paraissent pas avec la même fréquence. Ces fréquences varient suivant la langue utilisée. En
français, les lettres les plus rencontrées sont dans l’ordre :
ESAINTRULODCPMVQGFHBXJYZKW
avec les fréquences (souvent proches et dépendant de l’échantillon utilisé) :
E S A I N T R U L O D
14.69% 8.01% 7.54% 7.18% 6.89% 6.88% 6.49% 6.12% 5.63% 5.29% 3.66%
Voici la méthode d’attaque : dans le texte crypté, on cherche la lettre qui apparaît le plus, et si
le texte est assez long cela devrait être le chiffrement du E, la lettre qui apparaît ensuite dans
l’étude des fréquences devrait être le chiffrement du S, puis le chiffrement du A... On obtient
des morceaux de texte clair sous la forme d’une texte à trous et il faut ensuite deviner les lettres
manquantes.
L’espace des clés du chiffrement mono-alphabétique est immense, mais le fait qu’une lettre soit
toujours cryptée de la même façon représente une trop grande faiblesse. Le chiffrement de Vigenère
remédie à ce problème. On regroupe les lettres de notre texte par blocs, par exemple ici par blocs
de longueur 4 :
CETTE PHRASE NE VEUT RIEN DIRE
devient
CETT EPHR ASEN EVEU TRIE NDIR E
(les espaces sont purement indicatifs, dans la première phrase ils séparent les mots, dans la
seconde ils séparent les blocs).
Si k est la longueur d’un bloc, alors on choisit une clé constituée de k nombres de 0 à 25 :
(n 1 , n 2 , . . . , n k ). Le chiffrement consiste à effectuer un chiffrement de César, dont le décalage dépend
du rang de la lettre dans le bloc :
– un décalage de n 1 pour la première lettre de chaque bloc,
– un décalage de n 2 pour la deuxième lettre de chaque bloc,
– ...
– un décalage de n k pour la k-ème et dernière lettre de chaque bloc.
8
Pour notre exemple, si on choisit comme clé (3, 1, 5, 2) alors pour le premier bloc "CETT" :
– un décalage de 3 pour C donne F,
– un décalage de 1 pour E donne F,
– un décalage de 5 pour le premier T donne Y,
– un décalage de 2 pour le deuxième T donne V.
Ainsi "CETT" de vient "FFYV". Vous remarquez que les deux lettres T ne sont pas cryptées par
la même lettre et que les deux F ne cryptent pas la même lettre. On continue ensuite avec le
deuxième bloc...
Mathématiques
L’élément de base n’est plus une lettre mais un bloc, c’est-à-dire un regroupement de lettres. La
fonction de chiffrement associe à un bloc de longueur k, un autre bloc de longueur k, ce qui donne
en mathématisant les choses :
(
Z/26Z × Z/26Z × · · · × Z/26Z −→ Z/26Z × Z/26Z × · · · × Z/26Z
C n1 ,n2 ,...,n k :
(x1 , x2 , . . . , xk ) 7−→ (x1 + n 1 , x2 + n 2 , . . . , xk + n k )
Chacune des composantes de cette fonction est un chiffrement de César. La fonction de déchiffre-
ment est juste C −n1 ,−n2 ,...,−n k .
Il y a 26k choix possibles de clés, lorsque les blocs sont de longueur k. Pour des blocs de longueur
k = 4 cela en donne déjà 456 976, et même si un ordinateur teste toutes les combinaisons possibles
sans problème, il n’est pas question de parcourir cette liste pour trouver le message en clair, c’est-
à-dire celui qui est compréhensible !
Il persiste tout de même une faiblesse du même ordre que celle rencontrée dans le chiffrement
mono-alphabétique : la lettre A n’est pas toujours cryptée par la même lettre, mais si deux lettres
A sont situées à la même position dans deux blocs différents (comme par exemple "ALPH ABET")
alors elles seront cryptées par la même lettre.
Une attaque possible est donc la suivante : on découpe notre message en plusieurs listes, les
premières lettres de chaque bloc, les deuxièmes lettres de chaque bloc... et on fait une attaque
statistique sur chacun de ces regroupements. Ce type d’attaque n’est possible que si la taille des
blocs est petite devant la longueur du texte.
2.3. Algorithmes
Voici un petit algorithme qui calcule la fréquence de chaque lettre d’une phrase.
Algorithme . [Link]
def statistiques(phrase):
liste_stat = [0 for x in range(26)] # Une liste avec des 0
for lettre in phrase: # On parcourt la phrase
i = ord(lettre)-65
if 0 <= i < 26: # Si c'est une vraie lettre
liste_stat[i] = liste_stat[i] + 1
return(liste_stat)
9
Voici le principe du chiffrement : Alice veut envoyer à Bruno le message secret M suivant :
ATTAQUE LE CHATEAU
Alice a d’abord choisi une clé secrète C qu’elle a transmise à Bruno. Cette clé secrète est de la
même longueur que le message (les espaces ne comptent pas) et composée d’entiers de 0 à 25, tirés
au hasard. Par exemple C :
[4, 18, 2, 0, 21, 12, 18, 13, 7, 11, 23, 22, 19, 2, 16, 9]
Elle crypte la première lettre par un décalage de César donné par le premier entier : A est décalé
de 4 lettres et devient donc E. La seconde lettre est décalée du second entier : le premier T devient
L. Le second T est lui décalé de 2 lettres, il devient V. Le A suivant est décalé de 0 lettre, il reste
A... Alice obtient un message chiffré X qu’elle transmet à Bruno :
ELVALGW YL NEWMGQD
Pour le décrypter, Bruno, qui connaît la clé, n’a qu’à faire le décalage dans l’autre sens.
Notez que deux lettres identiques (par exemples les T) n’ont aucune raison d’être cryptées de la
même façon. Par exemple, les T du message initial sont cryptés dans l’ordre par un L, un V et un
M.
Formalisons un peu cette opération. On identifie A avec 0, B avec 1, ..., Z avec 25. Alors le message
crypté X est juste la "somme" du message M avec la clé secrète C, la somme s’effectuant lettre à
10
A T T A Q U E L E C H A T E A U
0 19 19 0 16 20 4 11 4 2 7 0 19 4 0 20
⊕
4 18 2 0 21 12 18 13 7 11 23 22 19 2 16 9
= 4 11 21 0 11 6 22 24 11 13 4 22 12 6 16 3
E L V A L G W Y L N E W M G Q D
Ce système appelé "masque jetable" ou chiffrement de Vernam est parfait en théorie, mais sa
mise en œuvre n’est pas pratique du tout ! Tout d’abord il faut que la clé soit aussi longue que le
message. Pour un message court cela ne pose pas de problème, mais pour envoyer une image par
exemple cela devient très lourd. Ensuite, il faut trouver un moyen sûr d’envoyer la clé secrète à
son interlocuteur avant de lui faire parvenir le message. Et il faut recommencer cette opération à
chaque message, ou bien se mettre d’accord dès le départ sur un carnet de clés : une longue liste
de clés secrètes.
Pour justifier que ce système est vraiment inviolable voici une expérience amusante : Alice veut
envoyer le message M ="ATTAQUE LE CHATEAU" à Bruno, elle choisit la clé secrète C=[4, 18,
2, 0,...] comme ci-dessus et obtient le message chiffré X ="ELVA..." qu’elle transmet à Bruno.
Alice se fait kidnapper par Chloé, qui veut l’obliger à déchiffrer son message. Heureusement, Alice
a anticipé les soucis : elle a détruit le message M, la clé secrète C et a créé un faux message M 0 et
une fausse clé secrète C 0 . Alice fournit cette fausse clé secrète C 0 à Chloé, qui déchiffre le message
par l’opération X ª C 0 et elle trouve le message bien inoffensif M 0 :
RECETTE DE CUISINE
Alice est innocentée !
Comment est-ce possible ? Alice avait au préalable préparé un message neutre M 0 de même lon-
gueur que M et calculé la fausse clé secrète C 0 = X ª M 0 . Chloé a obtenu (par la contrainte) X et
C 0 , elle déchiffre le message ainsi
X ª C 0 = X ª (X ª M 0 ) = (X ª X ) ⊕ M 0 = M 0
La machine Enigma est une machine électro-mécanique qui ressemble à une machine à écrire.
Lorsque qu’une touche est enfoncée, des disques internes sont actionnés et le caractère crypté
s’allume. Cette machine, qui sert aussi au déchiffrement, était utilisée pour les communications
de l’armée allemande durant la seconde guerre mondiale. Ce que les Allemands ne savaient pas,
c’est que les services secrets polonais et britanniques avaient réussi à percer les secrets de cette
machine et étaient capables de déchiffrer les messages transmis par les allemands. Ce long travail
d’études et de recherches a nécessité tout le génie d’Alan Turing et l’invention de l’ancêtre de
l’ordinateur.
Voici, dans ce cas, le processus de chiffrement du mot "BAC", avec la clé de chiffrement "G" :
1. Position initiale. L’opérateur tourne l’anneau intérieur de sorte que le A extérieur et fixe
soit en face du G intérieur (et donc B en face de W).
12
l’anneau intérieur numéro 1 a fait une rotation complète (26 lettres ont été tapées) alors l’anneau
intérieur numéro 2 effectue 1/26ème de tour. C’est comme sur un compteur kilométrique, lorsque
le chiffre des kilomètres parcourt 0, 1, 2, 3, ..., 9, alors au kilomètre suivant, le chiffre des kilomètres
est 0 et celui des dizaines de kilomètres est augmenté d’une unité.
S’il y a trois anneaux, lorsque l’anneau intérieur 2 a fait une rotation complète, l’anneau intérieur
3 tourne de 1/26ème de tour. Il y a alors 263 clés différentes facilement identifiables par les trois
lettres des positions initiales des anneaux.
Il fallait donc pour utiliser cette machine, d’abord choisir les disques (nos anneaux intérieurs) les
placer dans un certain ordre, fixer la position initiale de chaque disque. Ce système était rendu
largement plus complexe avec l’ajout de correspondances par fichage entre les lettres du clavier
(voir photo). Le nombre de clés possibles dépassait plusieurs milliards de milliards !
Commençons par rappeler que l’objectif est de générer une clé aléatoire de grande longueur. Pour
ne pas avoir à retenir l’intégralité de cette longue clé, on va la générer de façon pseudo-aléatoire à
partir d’une petite clé.
Voyons un exemple élémentaire de suite pseudo-aléatoire.
Soit (u n ) la suite définie par la donnée de (a, b) et de u 0 et la relation de récurrence
6 17 13 5 15 9 23 25 3 11 1 7 19 17 13 5
14
Les trois nombres (a, b, u 0 ) représentent la clé principale et la suite des (u n )n∈N les clés secondaires.
Avantages : à partir d’une clé principale on a généré une longue liste de clés secondaires. Inconvé-
nients : la liste n’est pas si aléatoire que cela, elle se répète ici avec une période de longueur 12 :
17, 13, 5, ..., 17, 13, 5, ...
Le système DES est une version sophistiquée de ce processus : à partir d’une clé courte et d’opéra-
tions élémentaires on crypte un message. Comme lors de l’étude de la machine Enigma, nous allons
présenter une version très simplifiée de ce protocole afin d’en expliquer les étapes élémentaires.
Pour changer, nous allons travailler modulo 10. Lorsque l’on travaille par blocs, les additions se
font bit par bit. Par exemple : [1 2 3 4] ⊕ [7 8 9 0] = [8 0 2 4] car (1 + 7 ≡ 8 (mod 10), 2 + 8 ≡ 0
(mod 10),...)
Notre message est coupé en blocs, pour nos explications ce seront des blocs de longueur 8. La clé
est de longueur 4.
Voici le message (un seul bloc) : M = [1 2 3 4 5 6 7 8] et voici la clé : C = [3 1 3 2].
M1 = [D 0 k C ⊕ σ(G 0 )]
M0 7−→ [5 6 7 8 k 1 2 3 4]
7−→ [5 6 7 8 k 2 3 4 1]
7−→ [5 6 7 8 k 5 4 7 3] = M1
M i+1 = [D i k C ⊕ σ(G i )]
M0 7−→ [5 4 7 3 k 5 6 7 8]
7−→ [5 4 7 3 k 6 7 8 5]
15
7−→ [5 4 7 3 k 9 8 1 7] = M2
Voici le texte original d’Auguste Kerckhoffs de 1883 «La cryptographie militaire» paru dans le
Journal des sciences militaires.
Il traite notamment des enjeux de sécurité lors des correspondances :
«Il faut distinguer entre un système d’écriture chiffré, imaginé pour un échange
momentané de lettres entre quelques personnes isolées, et une méthode de cryptogra-
phie destinée à régler pour un temps illimité la correspondance des différents chefs
d’armée entre eux.»
Le principe fondamental est le suivant :
«Dans le second cas, [. . . ] il faut que le système n’exige pas le secret, et qu’il
puisse sans inconvénient tomber entre les mains de l’ennemi.»
Ce principe est novateur dans la mesure où intuitivement il semble opportun de dissimuler le maxi-
mum de choses possibles : clé et système de chiffrement utilisés. Mais l’objectif visé par Kerckhoffs
est plus académique, il pense qu’un système dépendant d’un secret mais dont le mécanisme est
connu de tous sera testé, attaqué, étudié, et finalement utilisé s’il s’avère intéressant et robuste.
deux questions ne sont pas du même ordre de difficulté. Si je vous demande de factoriser 1591,
vous aller devoir faire plusieurs tentatives, alors que si je vous avais directement demandé de
calculer 37 × 43 cela ne pose pas de problème.
Pour des entiers de plusieurs centaines de chiffres le problème de factorisation ne peut être résolu
en un temps raisonnable, même pour un ordinateur. C’est ce problème asymétrique qui est à la
base de la cryptographie RSA (que nous détaillerons plus tard) : connaître p et q apporte plus
d’information utilisable que p × q. Même si en théorie à partir de p × q on peut retrouver p et q,
en pratique ce sera impossible.
Formalisons ceci avec la notion de complexité. La complexité est le temps de calculs (ou le nombre
d’opérations élémentaires) nécessaire pour effectuer une opération.
Commençons par la complexité de l’addition : disons que calculer la somme de deux chiffres (par
exemple 6 + 8) soit de complexité 1 (par exemple 1 seconde pour un humain, 1 milliseconde pour
un ordinateur). Pour calculer la somme de deux entiers à n chiffres, la complexité est d’ordre
n (exemple : 1234 + 2323, il faut faire 4 additions de chiffres, donc environ 4 secondes pour un
humain).
La multiplication de deux entiers à n chiffres est de complexité d’ordre n2 . Par exemple pour
multiplier 1234 par 2323 il faut faire 16 multiplications de chiffres (chaque chiffre de 1234 est à
multiplier par chaque chiffre de 2323).
1
Par contre la meilleure méthode de factorisation connue est de complexité d’ordre exp(4n 3 ) (c’est
moins que exp(n), mais plus que n d pour tout d, lorsque n tend vers +∞).
Voici un tableau pour avoir une idée de la difficulté croissante pour multiplier et factoriser des
nombres à n chiffres :
n multiplication factorisation
3 9 320
4 16 572
5 25 934
10 100 5 528
50 2 500 2 510 835
100 10 000 115 681 968
200 40 000 14 423 748 780
– Connaissant x, trouver y = f (x) est facile, cela nécessite deux multiplications et deux divi-
sions.
17
– soit utiliser la trappe secrète : y 7−→ y7 (mod 100) qui fournit directement le résultat !
La morale est la suivante : le problème est dur à résoudre, sauf pour ceux qui connaissent la trappe
secrète. (Attention, dans le cas de cet exemple, la fonction f n’est pas bijective.)
BRUNO
ALICE
En effet, jusqu’ici, les deux interlocuteurs se partageaient une même clé qui servait à chiffrer (et
déchiffrer) les messages. Cela pose bien sûr un problème majeur : Alice et Bruno doivent d’abord
se communiquer la clé.
BRUNO ALICE
Message crypté X
Chiffrement C Déchiffrement D
BRUNO
ALICE
De façon imagée, si Bruno veut envoyer un message à Alice, il dépose son message dans la boîte
aux lettres d’Alice, seule Alice pourra ouvrir sa boîte et consulter le message. Ici la clé publique
est symbolisée par la boîte aux lettre, tout le monde peut y déposer un message, la clé qui ouvre la
boîte aux lettres est la clé privée d’Alice, que Alice doit conserver à l’abri.
BRUNO ALICE
Clé publique
Message M Clé privée Message M
Message crypté X
Chiffrement C Déchiffrement D
En prenant appui sur l’exemple précédent, si le message initial est 71 et que la fonction f de
chiffrement est connue de tous, le message transmis est 11 et le déchiffrement sera rapide si la
trappe secrète 7 est connue du destinataire.
Les paramètres d’un protocole de chiffrement à clé publique sont donc :
– les fonctions de chiffrement et de déchiffrement : C et D ,
– la clé publique du destinataire qui va permettre de paramétrer la fonction C ,
– la clé privée du destinataire qui va permettre de paramétrer la fonction D .
Dans le cadre de notre exemple Bruno souhaite envoyer un message à Alice, ces éléments sont :
– C : x 7−→ x? (mod 100) et D : x 7−→ x? (mod 100),
– 3 : la clé publique d’Alice qui permet de définir complètement la fonction de chiffrement :
Dans la pratique, un chiffrement à clé publique nécessite plus de calculs et est donc assez lent,
plus lent qu’un chiffrement à clé privée. Afin de gagner en rapidité, un protocole hybride peut être
mis en place de la façon suivante :
– à l’aide d’un protocole de chiffrement à clé publique, Alice et Bruno échangent une clé,
– Alice et Bruno utilise cette clé dans un protocole de chiffrement à clé privée.
a p ≡ a (mod p)
et sa variante :
Corollaire 1
a p−1 ≡ 1 (mod p)
Nous allons voir une version améliorée de ce théorème dans le cas qui nous intéresse :
Soient p et q deux nombres premiers distincts et soit n = pq. Pour tout a ∈ Z tel que
pgcd(a, n) = 1 alors :
On note ϕ(n) = (p − 1)(q − 1), la fonction d’Euler. L’hypothèse pgcd(a, n) = 1 équivaut ici à ce que
a ne soit divisible ni par p, ni par q. Par exemple pour p = 5, q = 7, n = 35 et ϕ(n) = 4 · 6 = 24. Alors
pour a = 1, 2, 3, 4, 6, 8, 9, 11, 12, 13, 16, 17, 18, ... on a bien a24 ≡ 1 (mod 35).
Démonstration
où l’on appliquer le petit théorème de Fermat : a p−1 ≡ 1 (mod p), car p ne divise pas a.
Calculons ce même c mais cette fois modulo q :
où l’on appliquer le petit théorème de Fermat : a q−1 ≡ 1 (mod q), car q ne divise pas a.
Conclusion partielle : c ≡ 1 (mod p) et c ≡ 1 (mod q).
def euclide(a,b):
while b !=0 :
a , b = b , a % b
return a
On profite que Python assure les affectations simultanées, ce qui pour nous correspond aux suites
(
a i+1 = b i
b i+1 ≡ a i (mod b i )
initialisée par a 0 = a, b 0 = b.
Nous avons vu aussi comment « remonter » l’algorithme d’Euclide à la main pour obtenir les
coefficients de Bézout u, v tels que au + bv = pgcd(a, b). Cependant il nous faut une méthode plus
automatique pour obtenir ces coefficients, c’est l’algorithme d’Euclide étendu.
On définit deux suites (x i ), (yi ) qui vont aboutir aux coefficients de Bézout.
L’initialisation est :
x0 = 1 x1 = 0 y0 = 0 y1 = 1
def euclide_etendu(a,b):
x = 1 ; xx = 0
y = 0 ; yy = 1
while b != 0 :
q = a // b
a , b = b , a % b
xx , x = x - q*xx , xx
yy , y = y - q*yy , yy
return (a,x,y)
Cet algorithme renvoie d’abord le pgcd, puis les coefficients u, v tels que au + bv = pgcd(a, b).
Proposition 1
En d’autres termes, trouver un inverse de a modulo n revient à calculer les coefficients de Bézout
associés à la paire (a, n).
Démonstration
pgcd(a, n) = 1 ⇐⇒ ∃ u, v ∈ Z au + nv = 1
⇐⇒ ∃u ∈ Z au ≡ 1 (mod n)
Voici le code :
Algorithme . [Link] (3)
def inverse(a,n):
c,u,v = euclide_etendu(a,n) # pgcd et coeff. de Bézout
if c != 1 : # Si pgcd différent de 1 renvoie 0
return 0
else :
return u % n # Renvoie l'inverse
511 = 58 × 52 × 51 .
i
Calculons donc les 52 (mod 14) :
5 ≡ 5 (mod 14)
52 ≡ 25 ≡ 11 (mod 14)
54 ≡ 52 × 52 ≡ 11 × 11 ≡ 121 ≡ 9 (mod 14)
58 ≡ 54 × 54 ≡ 9 × 9 ≡ 81 ≡ 11 (mod 14)
Nous obtenons donc un calcul de 511 (mod 14) en 5 opérations au lieu de 10 si on avait fait
5×5×5···.
22
k i 2i .
X̀
k=
i =0
On obtient alors
P` i i
xk = x i =0 k i 2 (x2 )k i .
Ỳ
=
i =0
Par exemple 11 en base 2 s’écrit (1, 0, 1, 1), donc, comme on l’a vu :
3 2 1 0
511 = (52 )1 × (52 )0 × (52 )1 × (52 )1 .
Voici un autre exemple : calculons 17154 (mod 100). Tout d’abord on décompose l’exposant k = 154
en base 2 : 154 = 128 + 16 + 8 + 2 = 27 + 24 + 23 + 21 , il s’écrit donc en base 2 : (1, 0, 0, 1, 1, 0, 1, 0).
Ensuite on calcule 17, 172 , 174 , 178 , ..., 17128 modulo 100.
17 ≡ 17 (mod 100)
172 ≡ 17 × 17 ≡ 289 ≡ 89 (mod 100)
174 ≡ 172 × 172 ≡ 89 × 89 ≡ 7921 ≡ 21 (mod 100)
178 ≡ 174 × 174 ≡ 21 × 21 ≡ 441 ≡ 41 (mod 100)
1716 ≡ 178 × 178 ≡ 41 × 41 ≡ 1681 ≡ 81 (mod 100)
1732 ≡ 1716 × 1716 ≡ 81 × 81 ≡ 6561 ≡ 61 (mod 100)
1764 ≡ 1732 × 1732 ≡ 61 × 61 ≡ 3721 ≡ 21 (mod 100)
17128 ≡ 1764 × 1764 ≡ 21 × 21 ≡ 441 ≡ 41 (mod 100)
17154 ≡ 17128 × 1716 × 178 × 172 ≡ 41 × 81 × 41 × 89 ≡ 3321 × 3649 ≡ 21 × 49 ≡ 1029 ≡ 29 (mod 100)
def puissance(x,k,n):
puiss = 1 # Résultat
while (k>0):
if k % 2 != 0 : # Si k est impair (i.e. k_i=1)
puiss = (puiss*x) % n
x = x*x % n # Vaut x, x^2, x^4,...
k = k // 2
return(puiss)
En fait Python sait faire l’exponentiation rapide : pow(x,k,n) pour le calcul de a k modulo n, il
faut donc éviter (x ** k) % n qui n’est pas adapté.
6. Le chiffrement RSA
Voici le but ultime de ce cours : la chiffrement RSA. Il est temps de relire l’introduction du chapitre
« Arithmétique » pour s’apercevoir que nous sommes prêts !
23
Dans cette section, c’est Bruno qui veut envoyer un message secret à Alice. La processus se décom-
pose ainsi :
1. Alice prépare une clé publique et une clé privée,
2. Bruno utilise la clé publique d’Alice pour crypter son message,
3. Alice reçoit le message crypté et le déchiffre grâce à sa clé privée.
Alice effectue, une fois pour toute, les opérations suivantes (en secret) :
– elle choisit deux nombres premiers distincts p et q (dans la pratique ce sont de très grand
nombres, jusqu’à des centaines de chiffres),
– Elle calcule n = p × q,
– Elle calcule ϕ(n) = (p − 1) × (q − 1).
Exemple 1.
– p = 5 et q = 17
– n = p × q = 85
– ϕ(n) = (p − 1) × (q − 1) = 64
Vous noterez que le calcul de ϕ(n) n’est possible que si la décomposition de n sous la forme p × q
est connue. D’où le caractère secret de ϕ(n) même si n est connu de tous.
Exemple 2.
– p = 101 et q = 103
– n = p × q = 10 403
– ϕ(n) = (p − 1) × (q − 1) = 10 200
Alice continue :
– elle choisit un exposant e tel que pgcd(e, ϕ(n)) = 1,
– elle calcule l’inverse d de e module ϕ(n) : d × e ≡ 1 (mod ϕ(n)). Ce calcul se fait par l’algo-
rithme d’Euclide étendu.
Exemple 1.
– Alice choisit par exemple e = 5 et on a bien pgcd(e, ϕ(n)) = pgcd(5, 64) = 1,
24
– Alice applique l’algorithme d’Euclide étendu pour calculer les coefficients de Bézout corres-
pondant à pgcd(e, ϕ(n)) = 1. Elle trouve 5 × 13 + 64 × (−1) = 1. Donc 5 × 13 ≡ 1 (mod 64) et
l’inverse de e modulo ϕ(n) est d = 13.
Exemple 2.
– Alice choisit par exemple e = 7 et on a bien pgcd(e, ϕ(n)) = pgcd(7, 10 200) = 1,
– L’algorithme d’Euclide étendu pour pgcd(e, ϕ(n)) = 1 donne 7 × (−1457) + 10 200 × 1 = 1. Mais
−1457 ≡ 8743 (mod ϕ(n)), donc pour d = 8743 on a d × e ≡ 1 (mod ϕ(n)).
Clé publique
n et e
Et comme son nom l’indique Alice communique sa clé publique au monde entier.
Exemple 1. n = 85 et e = 5
Exemple 2. n = 10 403 et e = 7
Clé privée
Alice détruit en secret p, q et ϕ(n) qui ne sont plus utiles. Elle conserve secrètement sa clé privée.
Exemple 1. d = 13
Exemple 2. d = 8743
Bruno veut envoyer un message secret à Alice. Il se débrouille pour que son message soit un entier
(quitte à découper son texte en bloc et à transformer chaque bloc en un entier).
Message
Message chiffré
Bruno récupère la clé publique d’Alice : n et e avec laquelle il calcule, à l’aide de l’algorithme
d’exponentiation rapide, le message chiffré :
x ≡ m e (mod n)
m ≡ x d (mod n)
Calculons à la main 4013 ≡ (mod 85) on note que 13 = 8 + 4 + 1, donc 4013 = 408 × 404 × 40.
n, e d
? x ≡ m e (mod n) ?
m - C - D - m ≡ x d (mod n)
Bruno Alice
6.4. Schéma
Clés d’Alice :
– publique : n, e
– privée : d
Lemme 1
Ce lemme prouve bien que le message original m de Bruno, chiffré par clé publique d’Alice (e, n)
en le message x, peut-être retrouvé par Alice à l’aide de sa clé secrète d.
Démonstration
– Que d soit l’inverse de e modulo ϕ( n) signifie d · e ≡ 1 (mod ϕ( n)). Autrement dit, il existe k ∈ Z
tel que d · e = 1 + k · ϕ( n).
– On rappelle que par le petit théorème de Fermat généralisé : lorsque m et n sont premiers entre
eux
mϕ(n) ≡ m( p−1)( q−1) ≡ 1 (mod n)
( m e )d ≡ m (mod n)
27
6.6. Algorithmes
La mise en œuvre est maintenant très simple. Alice choisit deux nombres premiers p et q et un
exposant e.
Voici le calcul de la clé secrète :
Algorithme . [Link] (1)
def cle_privee(p,q,e) :
n = p * q
phi = (p-1)*(q-1)
c,d,dd = euclide_etendu(e,phi) # Pgcd et coeff de Bézout
return(d % phi) # Bon représentant
Le chiffrement d’un message m est possible par tout le monde, connaissant la clé publique (n, e).
Algorithme . [Link] (2)
def codage_rsa(m,n,e):
return pow(m,e,n)
def decodage_rsa(x,n,d):
return pow(x,d,n)
Pour continuer...
Bibliographie commentée :
1. Histoire des codes secrets de Simon Singh, Le livre de Poche.
Les codes secrets racontés comme un roman policier. Passionnant. Idéal pour les plus litté-
raires.
2. Comprendre les codes secrets de Pierre Vigoureux, édition Ellipses.
Un petit livre très clair et très bien écrit, qui présente un panorama complet de la cryptogra-
phie sans rentrer dans les détails mathématiques. Idéal pour les esprits logiques.
3. Codage et cryptographie de Joan Gómez, édition Le Monde – Images des mathématiques.
Un autre petit livre très clair et très bien, un peu de maths, des explications claires et des
encarts historiques intéressants.
4. Introduction à la cryptographie de Johannes Buchmann, édition Dunod.
Un livre d’un niveau avancé (troisième année de licence) pour comprendre les méthodes
mathématiques de la cryptographie moderne. Idéal pour unifier les points de vue des mathé-
matiques avec l’informatique.
5. Algèbre - Première année de Liret et Martinais, édition Dunod.
Livre qui recouvre tout le programme d’algèbre de la première année, très bien adapté aux
étudiants des l’université. Pas de cryptographie.
28
Auteurs
Arnaud Bodin
François Recher