C15.4 : TD - Chiffrement KidRSA
Dans ce TP, nous allons utiliser une version plus simplifiée du chiffrement RSA nommée KidRSA.
1. Le chiffrement RSA est un « chiffrement asymétrique ». Expliquer la signification de ce terme.
Partie A : Implémentation du chiffrement KidRSA
Un exemple (avec des petits nombres)
Prenons \(a_1 = 5\), \(b_1 = 3\), \(a_2 = 7\) et \(b_2 = 5\).
2. Calculer \(M\), \(e\), \(d\) et \(n\).
3. En déduire la clé publique et la clé privée.
4. A chaque caractère, on associe son point de code unicode.
On pourra utiliser les fonctions ord(caractere) et chr(entier) qui permettent de connaitre le point de code d’un caractère et inversement.
On s’intéresse à la lettre 'a' dont le point de code unicode est 97.
4.a. Qu’elle valeur obtient-on en chiffrant la lettre 'a' ?
4.b. Montrer que le déchiffrement à l’aide de la clé privée est correct.
Implémentation en Python du chiffrement KidRSA
5. Écrire le code de la fonction genere_cles_publique_et_privee(a1, b1, a2, b2), qui calcul et retourne la clé publique (e, n) et la clé privée (d, n) sous forme de deux tuples à partir des quatre entiers a1, b1, a2, b2 passés en paramètres.
6. Écrire le code de la fonction chiffre_message(m, cle) qui prend une chaine de caractère m et un tuple cle en paramètres et renvoie le message chiffré sous la forme d’une liste de nombre entiers.
7. Écrire la fonction dechiffre_message(li, cle) qui déchiffre un message li qui est une liste de nombres entiers et renvoie le message déchiffré sous la forme d’une chaîne de caractères.
Tests de cette implémentation en Python de KidRSA
On choisit comme valeurs \(a_1 = 13\), \(b_1 = 32\), \(a_2 = 69\) et \(b_2 = 35\).
8. Donner les valeurs de la clé publique et de la clé privée.
9. Donner la liste chiffrée correspondant à la chaîne de caractères 'NSI' en utilisant la clé publique.
10. Vérifier que le déchiffrement de la liste obtenue avec la clé privée redonne bien le message 'NSI'.
Partie B : Décryptage du chiffrement KidRSA par la force brute
La force brute
Un message a été chiffré avec KidRSA à l’aide de la clé publique suivante \((e, n) = (53447, 5185112)\).
Voici le message chiffré obtenu :
[3580949, 2084433, 3687843, 4436101, 4489548, 1710304, 4329207, 4542995, 3901631, 1710304, 4061972, 3687843, 1710304, 3527502, 4222313, 4436101, 4436101, 1710304, 3687843, 4168866, 1710304, 4168866, 4436101, 3901631, 1710304, 3367161]
On souhaite décrypter le message chiffré pour retrouver le message clair. Pour cela, on a besoin de connaître la clé privée \((d, n)\). Comme on connait déjà \(n\) (\(n = 5185112\)), il faut trouver une méthode pour calculer \(d\).
La relation entre les nombres \(e\), \(d\) et \(n\) des clés publique et privée donne : \(e×d-1=n×M\).
On en déduit que \((e×d-1)\) est divisible par \(n\).
Pour trouver l’entier \(d\) qui fait partie de la clé privée, comme on connait déjà \(e\) et \(n\), il suffit d’étudier parmi toutes les valeurs de \(d\) comprises entre \(1\) et \(n-1\), celle qui vérifie la condition « \(e × d - 1\) est divisible par \(n\) ».
On appelle ce type d’attaque « attaque par force brute » car on doit étudier (dans le pire des cas) tous les entiers \(d\) inférieurs à \(n\), ce qui peut être long si \(n\) est grand.
11. Écrire le corps de la fonction bruteForceKidRSA(e, n) qui calcule et qui renvoie le premier entier \(d\) inférieur à \(n\) qui vérifie la relation « \(e×d-1\) est divisible par \(n\) ».
12. En déduire la valeur de \(d\) pour la clé publique proposée puis déchiffrer le message.
Limite de la force brute
La réponse au message chiffré précédent est aussi chiffrée avec KidRSA mais avec une clé publique de longueur beaucoup plus grande.
Voici la clé publique utilisée : \((e, n) = (230884490440319, 194326240259798261076)\).
Et voici le message chiffré obtenu avec la clé publique :
[20548719649188391, 25628178438875409, 27013485381517323, 7388303694090208, 22395795572710943, 26320831910196366, 23319333534472219, 7388303694090208, 26782600891077004, 24011987005793176, 23319333534472219, 7388303694090208, 24704640477114133, 24242871496233495, 25397293948435090, 23781102515352857, 7388303694090208, 25628178438875409, 23550218024912538, 7388303694090208, 26782600891077004, 24011987005793176, 23319333534472219, 7388303694090208, 22626680063151262, 25628178438875409, 26551716400636685, 26551716400636685, 23319333534472219, 26551716400636685, 7388303694090208, 7619188184530527, 2307921366441428724]
13. Essayer de retrouver la clé privée à l’aide de la fonction précédente. Quel est le problème rencontré ?
Partie C : Décryptage avec l'algorithme d'Euclide étendu
L'attaque par force brute n'est pas envisageable lorsque la clé est trop longue. Il existe une méthode plus efficace basée sur l'algorithme d'Euclide étendu. L'algorithme d'Euclide étendu est beaucoup plus efficace que l'attaque par force brute car sa complexité en temps est, dans le pire car, en \(\mathcal O(log(n))\) alors que celle de l'attaque par force brute est en \(\mathcal O(n)\).
Le principe de l'algorithme KidRSA permet d'écrire que \(e×d - n×M = 1\), où \((e,n)\) est la clé publique, donc \(e\) et \(n\) sont connus.
L'application de l'algorithme d'Euclide étendu permet de trouver \(d\) (et \(M\)).
14. En appliquant l'algorithme d'Euclide étendu "à la main", retrouver la clé privée associé à la clé publique \((17,55)\).
Le code ci-dessous est une implémentation récursive de l'algorithme d'Euclide étendu.
def euclide_etendu(a, b):
"""
Paramètres :
a (int) : un entier strictement positif tel que a et b soient premiers entre eux.
b (int) : un entier strictement positif tel que a et b soient premiers entre eux.
Valeur renvoyée
(tpl) : un triplet d'entiers donnant le pgcd, et les deux coefficients de Bézout.
"""
if a == 0:
return (b, 0, 1)
else:
r, y, x = euclide_etendu(b % a, a)
return (r, x - (b//a) * y, y)
15. En utilisant la fonction précédente, écrire une fonction qui prend une clé publique en paramètre et renvoie la clé privée correspondant.
16. Retrouver, "informatiquement", les valeurs de la question 14.
17. En déduire la clé privée associée à la clé publique : \((230884490440319, 19432624025979826176)\).
18. Décrypter le message de la question 13.
Compléments
• Lien sur interstices.info : Clés RSA
• Lien : Algorithme d'Euclide étendu sous sa forme récurrente