Séance no 3 : Autour de RSA 1 Présentation de RSA

publicité
Univ. Lille 1 - IREM de Lille.
2010-2011
Stage Algorithmique
Séance n 3 : Autour de RSA
o
Éric Wegrzynowski. (Eric.Wegrzynowski (a) univ-lille1.fr)
1 Présentation de RSA
En 1976, W. Die et M. E. Hellman, préoccuppés par le problème de l'échange de clés
cryptographiques, ont introduit le concept de cryptographie à clé publique. Un an plus tard,
Ronald Rivest, Adi Shamir et Leonard Adleman proposaient l'une des premières réalisations de
système cryptographique à clé publique connu sous le nom de RSA.
Un système de chirement cryptographique est dit à clé publique (on dit aussi asymétrique )
lorsque la clé utilisée pour l'opération de chirement est connue de tous, et que la clé utilisée
pour l'opération de déchirement n'est connue que de son seul titulaire. Les clés vont donc par
paire. Chaque individu possède une paire de clés :
une clé qu'il peut rendre publique et que toute personne, désirant lui envoyer un message
condentiel, peut utiliser pour le chirer ;
et une clé privée qu'il est seul à connaître, et qu'il utilise pour déchirer les messages chirés
qu'il reçoit.
Les systèmes cryptographiques à clé publique reposent sur la notion de fonction à sens unique
avec trappes.
Une fonction à sens unique est une fonction dont il est facile de calculer les valeurs, mais qu'il
est dicile d'inverser. Autrement dit, une fonction f : A → B est à sens unique si pour tout
x ∈ A il est facile de calculer son image f (x), et s'il est dicile de résoudre l'équation y = f (x),
pour presque tout y ∈ B 1 .
Par exemple, calculer le produit de deux nombres entiers est facile. Mais factoriser un entier
est un problème algorithmique beaucoup plus dicile.
On peut le vérier avec
. La multiplication de deux nombres entiers de plus de 20 chires
est instantanée :
Xcas
> 123456789098765445817313 * 987654321012345680423311
121932631211705546391262024498778384392212583343
// Time 0
mais la factorisation du produit demande beaucoup plus de temps :
> ifactor (121932631211705546391262024498778384392212583343)
Evaluation time: 3.19
123456789098765445817313*987654321012345680423311
// Time 3.19
Dans le cas de RSA, la fonction à sens unique est l'élévation d'un entier à une certaine
puissance modulo un nombre : f (x) = xe mod n, où x est un entier modulo n. On a donc ici
A = B = Z/nZ. Comme nous le vérierons plus bas, le calcul de f (x) est facile, mais la résolution
de l'équation y = f (x) ne l'est pas ... pour qui ne connaît pas un secret supplémentaire : la trappe.
Voyons cela d'un peu plus près.
1. Cette dénition est assez informelle puisqu'elle emploie des termes vagues comme facile et dicile. On
peut rendre rigoureuse la dénition des fonctions à sens unique en requérant à la théorie de la complexité des
problèmes.
1
Si Alice souhaite envoyer un message m condentiel à Bob en utilisant le système RSA, elle
devra se procurer la clé publique de Bob. Cette clé est un couple de deux entiers n et e que Bob
a choisi au préalable.
L'entier n, appelé modulus, est un produit de deux nombres premiers distincts p et q . Par
exemple, avec p = 17 et q = 23, le modulus vaut n = 391.
> p := 17; q := 23; n := p*q
17,23,391
L'entier e, appelé exposant de chirement, est un entier premier avec ϕ(n) = (p − 1)(q − 1).
Dans notre exemple, ϕ(n) = 352 et l'entier e = 3 convient.
> phi := (p - 1) * (q - 1); E := 3; igcd(E,phi)
352,3,1
Lorsqu'Alice a connaissance de la clé publique de Bob, elle peut chirer son message m en
calculant me mod n (un message est donc nécessairement un entier compris entre 0 et n − 1).
Dans notre exemple, si Alice veut transmettre le message m = 21, elle calcule
> m := 21; c := irem(m^E,n)
21,268
et le message chiré est ainsi c = 268 qu'elle transmet à Bob.
De son côté, Bob a conservé un entier qu'il n'a communiqué à personne : c'est sa
que l'on notera d. Cette clé privée est reliée à la clé publique par la relation
d = e−1
clé privée
mod ϕn,
autrement dit d est l'inverse de e dans l'anneau Z/ϕ(n)Z. Dit encore autrement, l'entier produit
ed est congru à 1 modulo ϕ(n). Dans notre exemple d = 235
> d := irem(1/E,phi)
235
Cette clé privée est ce qui lui permet de retrouver le message clair qu'Alice lui a envoyé. En eet,
s'il eectue le calcul cd mod n, Bob retrouve ce message.
> irem(c^d,n)
21
Eve, qui écoute la conversation d'Alice et Bob, cherche à découvrir quel est le message clair m
caché dans le message chiré c. Elle connaît bien entendu la clé publique de Bob (puisqu'elle est
publique !), et elle sait donc que m est solution de l'équation c = xe mod n . Son but est donc de
résoudre cette équation. Malheureusement, elle ne connaît aucun algorithme ecace (en temps
polynomial) de résolution de ce type d'équation. Bien entendu, elle peut toujours envisager de
rechercher de manière exhaustive la solution de cette équation en parcourant tous les entiers
possibles compris entre 0 et n − 1, mais cette recherche est hors de portée du plus puissant de
tous les ordinateurs si n est susamment grand, un nombre de plus de 300 chires par exemple.
Pour résumer :
Tout le monde peut avoir connaissance de la clé publique de Bob et lui envoyer des messages
chirés.
Mais seul Bob a la possibilité de déchirer les messages qu'on lui envoie car il est le seul à
connaître sa clé privée (la trappe).
2
Sommaire de ce qui suit :
1. Algorithme d'exponentiation modulaire rapide : ou comment eectuer en pratique les opérations de chirement/déchirement (voir 2).
2. Fabriquer des paires de clés RSA : tests de primalité (voir 3).
3. Petits exercices pour s'imprégner de RSA (cf 4).
2 Chirer et déchirer un message
Dans le système RSA, chirer un message m ∈ Z/nZ c'est calculer
c = me
mod n,
où le couple (n, e) est la clé publique du destinataire du message. Le chiré c étant alors lui-même
dans Z/nZ.
Déchirer le message c, c'est calculer
cd
mod n,
où d est la clé privée de ce destinataire.
Les deux opérations de chirement et de déchirement sont donc des opérations analogues :
une exponentiation modulaire.
Si pour de petits nombres entiers, il est envisageable d'eectuer ces calculs en calculant
l'exponentiation d'abord, puis en calculant la réduction modulo n ensuite, il en est hors de
question pour les clés RSA utilisées dans la pratique pour lesquelles les nombres qui interviennent
ont plusieurs centaines de chires.
Lorsque dans l'exemple de la partie précédente on a chiré le message m = 21 avec la clé
publique (n, e) = (391, 3) en utilisant la fonction irem, le calcul eectué est réellement fait dans
les deux étapes décrites
> c1 := m^E
9261
> c := irem(9261,391)
268
et pour le déchirement, on a calculé d'abord
> m1 := c^d
4089560117124007355657007736693321034991773165026904638413048272\
0800981002743586222766326155798159208215524073816058399333380883\
4384196828144470725130828501536909280406518640876128180685816925\
0351277719188277596474711895159558519004569133385723126442099218\
5797845696054787887695873641521080669480895250118199474170802881\
8497920131116203565047945579665881953153361062259887760602654159\
5245494348238828886172913050474449650143745888778185461245859609\
9573533910284157482187242176850574398902255785475245635075199855\
33733186687853729012776947577894961992523366944441664274432
puis
> irem(m1,391)
21
3
Comme on le voit ce calcul fait apparaître un nombre intermédiaire m1 de 571 chires décimaux !
> floor(log10(m1)) + 1
571
Ce procédé de calcul n'est donc pas la bonne façon de chirer/déchirer des messages en RSA
lorsque les clés sont grandes (rappelons plusieurs centaines de chires).
La fonction prédénie powmod calcule ab mod n en suivant l'algorithme d'exponentiation
modulaire rapide (). Elle peut donc être utilisée avec de grands entiers.
> n := 123456789098765445817313 * 987654321012345680423311
121932631211705546391262024498778384392212583343
> a := 170980768765876465354365589709809
170980768765876465354365589709809
> b := 8768765465345576897098098098765765
8768765465345576897098098098765765
> powmod (a,b,n)
36701901377014928599189626904411362528587198281
Au travail (1) !
Calculez le nombre de chires (en base 10) du nombre entier ab .
3 Générer une paire de clés RSA
3.1 Trouver des nombres premiers
Un nombre entier au moins égal à 2 est premier s'il n'est divisible que par 1 et lui-même, dans
le cas contraire il est composé . La fonction isprime de
permet de tester si un nombre est
premier.
Quelques exemples :
Xcas
> isprime(2)
vrai
> isprime(3)
vrai
> isprime(4)
faux
Pour fabriquer des clés RSA, il faut pouvoir trouver des nombres premiers de plusieurs centaines de chires. Comment s'y prendre ?
Pour des raisons de sécurité, il est hors de question d'imaginer une table (ou une base de
données) dans laquelle chacun irait les puiser. Et de toute façon cette table pourrait être bien
trop grosse. Combien y a-t-il de nombres premiers dans un intervalle donné ?
Une solution consiste à choisir un nombre au hasard, à tester s'il est premier. Si c'est le cas
on a gagné, sinon on recommence.
Voici un exemple de mise en oeuvre de cette méthode pour trouver un nombre premier compris
entre 100 et 1000. On utilise la fonction rand qui paramétrée avec un entier positif k renvoie un
nombre au hasard compris entre 0 et k − 1, ce nombre n'étant pas nécessairement un nombre
entier lorsque k est grand. Et la fonction isprime renvoie la valeur booléenne vrai si l'entier
qu'on lui donne est un nombre premier, et la valeur faux dans le cas contraire.
4
n := 100 + floor(rand (900)) ;
tantque not(isprime(n)) faire
n := 100 + floor(rand (900)) ;
ftantque ;
n
Parmi les nombres n tirés au hasard par cette méthode, en moyenne un sur deux
est pair et évidemment non premier. Améliorez la méthode pour éviter d'avoir à tester la primalité de
nombres pairs.
Au travail (2) !
Au travail (3) ! Réalisez en Xcas une fonction gen_premier paramétrée par un entier t et qui renvoie
un nombre premier choisi au hasard ayant t chires en base 10.
Vous voici en mesure de créer automatiquement un modulus n d'une paire de clés RSA.
Au travail (4) ! Engendrez deux nombres premiers p et q de 10 chires, pui obtenez un modulus
n = pq et le nombre ϕ(n) = (p − 1)(q − 1). Attention, assurez vous que p 6= q , ce qui doit être le cas avec
une très forte probabilité.
3.2 Les exposants de chirement/déchirement
Une fois le modulus n obtenu il vous faut obtenir deux exposants de chirement et de déchirement.
L'exposant de chirement e doit être premier avec ϕ(n).
e peut-il être pair ?
Au travail (5) !
La fonction igcd calcule le pgcd de deux entiers.
Trouvez le plus petit exposant de chirement qui convient pour votre modulus. Puis,
Au travail (6) !
le plus grand.
Une fois l'exposant de chirement xé, on calcule l'exposant de déchirement d en se souvenant qu'il est l'inverse de e modulo ϕ(n). Cet inverse peut être calculé avec l'algorithme d'Euclide étendu qui en plus du pgcd donne les deux coecients de Bezout. En
, c'est ce que
fait la fonction irem en l'appliquant à 1/e et ϕ(n).
Xcas
Au travail (7) !
trouvés plus haut.
Calculez les exposants de déchirement pour chacun des deux exposants de chirement
Vous avez une paire de clés RSA : (n, e) clé publique, d clé privée.
Chirez/déchirez le message de votre choix. Souvenez-vous que le message doit être
un entier plus petit que votre modulus.
Au travail (8) !
Réalisez une fonction gen_rsa paramétrée par un entier t qui renvoie une liste
[n, e, d, p, q] constituée d'un modulus n de 2t chires, d'un exposant de chirement e, d'un exposant de
déchirement d, et des deux nombres premiers p et q qui composent n.
Au travail (9) !
3.3 Tests de primalité
Comment fonctionne la fonction isprime ? Comment tester la primalité d'un nombre entier.
5
3.3.1
Test par recherche du plus petit diviseur
L'une des méthodes les plus élémentaires consiste à rechercher le plus petit diviseur au moins
égal à deux de l'entier n à tester (que l'on suppose être au moins égal à 2). Cette recherche peut
se faire de manière systématique en incrémentant une variable k initialisée à 2. On peut arrêter
la recherche
si on a trouvé un entier 2 ≤ k <√n qui divise n,
ou bien si la variable k dépasse n.
Réalisez une fonction est_premier1 qui teste la primalité d'un entier en suivant cet
Au travail (10) !
algorithme.
Ce test de primalité convient-il aux nombres premiers de plusieurs dizaines, voire
centaines de chires ?
Au travail (11) !
3.3.2
Le (petit) théorème de Fermat
Le théorème de Fermat stipule que si n est un nombre premier, alors pour tout entier a non
multiple de n, on a
a( n − 1) mod n = 1.
En particulier, pour tout entier 1 ≤ a < n, on a an−1 mod n = 1.
Malheureusement la réciproque n'est pas vraie. Néanmoins, on peut utiliser ce théorème pour
prouver que des nombres ne sont pas premiers, en suivant l'algorithme :
1. On tire au hasard un entier a compris entre 1 et n − 1
2. On calcule an−1 mod n
3. Si le nombre obtenu est diérent de 1 alors conclure que n n'est pas premier. Sinon, on ne
peut rien conclure.
Dans le cas où le nombre calculé à partir de a vaut 1, rien ne dit que n est premier. On peut
recommencer en choisissant un nouvel entier a au hasard.
Mais dans le cas où ce nombre ne vaut pas 1, alors a est une preuve de non primalité de n
qu'on appelle témoin de non primalité.
Au travail (12) !
Programmez une fonction nommée test_fermat qui prend deux entiers en paramètre :
n ≥ 2 l'entier dont on veut tester la primalité, et nb le nombre d'essai maximal eectué pour trouver
un témoin de non primalité, et qui renvoie un témoin de non primalité de n si on en trouve un, ou alors
l'entier -1 si au bout de nb tentatives aucun témoin n'a été trouvé.
Malheureusement certains nombres font échouer (presque) systématiquement ce test. Ce sont
les nombres de Carmichael, le plus petit d'entre eux étant 561.
3.3.3
Le test de Miller-Rabin
Le test de Miller-Rabin s'appuie sur un ranement du théorème de Fermat.
Supposons que l'entier impair n soit premier, et considérons les deux entiers s et t tels que
n − 1 = 2s t,
avec t impair.
Soit a un entier premier avec n. Alors
1. ou bien at mod n = 1 (1),
i
2. ou bien il existe un entier i compris entre 0 et s − 1 tel que : a2
6
t
mod n = −1 (2).
Si on trouve un entier a compris entre 2 et n − 2 tel que l'équation (1) ne soit pas vraie et
tel qu'il n'existe aucun entier i satisfaisant une équation (2), alors on est certain que n n'est pas
premier, et on dit que a est un témoin de la non primalité de n.
Un théorème dû à Rabin montre que si n est impair et au moins égal à 11, alors au moins
3ϕ(n)/4 entiers compris entre 1 et n − 1 sont des témoins de non primalité.
4 Petits exercices
Dans cette partie, et pour s'amuser, nous allons chirer/déchirer des messages textuels que
nous convertirons en nombres 2 .
4.1 Deux fonctions Xcas utiles
La fonction asc donne la liste des codes ASCII des caractères qui compose la chaîne qu'on
lui donne à traiter. Voici un exemple avec la chaîne de caractères "STAGE"
> asc("STAGE")
[83,84,65,71,69]
qui donne la liste des codes des cinq lettres qui composent cette chaîne (83 pour le S, 84 pour le
T, . . . ). Les caractères ont des codes tous situés entre 0 et 255.
Nous allons codé numériquement de petits messages. Pour cela nous considèrerons toute
chaîne de caractères comme un entier écrit en base 256, les chires de cette écriture étant les
codes des caractères, et les puissances de la base allant en croissant dans une lecture de gauche
à droite de la chaîne. Par exemple, le mot "STAGE" est codé par l'entier
83 × 2560 + 84 × 2561 + 65 × 2562 + 71 × 2563 + 69 × 2564 = 297548207187.
La fonction texte_en_nombre décrite ci-dessous eectue ce calcul en suivant un algorithme
d'évaluation de fonction polynomiale connu sous le nom d'algorithme de Horner. C'est un algorithme simple qui minimise le nombre d'opérations arithmétiques (additions et multiplications).
Pour évaluer un polynôme de degré n on eectue n additions et n multiplications. Sur notre
exemple, le mot "STAGE" étant de longueur 5, le polynôme est de degré 4 et cinq additions et
multiplications susent pour calculer l'entier associé :
83 + 256 × (84 + 256 × (65 + 256 × (71 + 256 × 69))) = 297548207187.
// conversion d’une chaine en un nombre entier
chaine_en_nombre (s) := {
local l, res, k;
l := asc(s) ;
res := 0 ;
pour k de lenght(l) - 1 jusque 0 pas -1 faire
res := res * 256 + l[k] ;
fpour ;
retourne res ;
}
2. Dans la pratique, RSA est très rarement utilisé pour chirer des messages textuels. On l'utilise en général
pour chirer de petites données binaires, comme des clés secrètes de chirement symétrique.
7
Appliqué à la chaîne "STAGE", on obtient
> chaine_en_nombre("STAGE")
297548207187
Pour la fonction inverse on utilise la fonction prédénie char qui convertit un nombre compris
entre 0 et 255 en la chaîne d'un caractère correspondant.
> char (65)
"A"
// conversion d’un nombre en une chaine
nombre_en_chaine (n) := {
local res, m, r;
m := n ;
res := "" ;
tantque m >= 256 faire
r := irem (m, 256) ;
res := res + char (r) ;
m := iquo (m, 256) ;
ftantque ;
retourne (res + char(m)) ;
}
> nombre_en_texte (297548207187)
"STAGE"
On aurait pu aussi programmer de manière plus concise cette fonction en utilisant la fonction
prédénie convert avec l'option base. Puis appliquer à la liste résultante la fonction char.
> l := convert(297548207187,base,256)
[83,84,65,71,69]
> char (l)
"STAGE"
Réalisez une fonction nommée chiffrer_message paramétrée par un message m
sous forme d'une chaîne de caractères et deux entiers e et n clé publique RSA, et qui renvoie la liste des
entiers qui composent le message chiré.
Au travail (13) !
Réalisez la fonction réciproque dechiffrer_message paramétrée par une liste d'entiers représentant un message chiré et deux entiers d et n et qui calcule le message clair correspondant.
Au travail (14) !
4.2 Déchirement 1
La paire de clés RSA utilisée dans cet exercice est
(n, e) = (14570880473514810869, 5)
d = 11656704370699282877.
Déchirez le message
1135856993533935716, 538172911971812535,
9678757407856715762, 4264715098502195642,
9470071105153682952
8
4.3 Déchirement 2
Le message ci-dessous a été chiré avec la clé publique (n, e) = (35089646366518232603, 5).
La clé privée est l'une des trois ci-dessous. Retrouvez-la et déchirez le message.
d1 = 21053787812793595467.
d2 = 21053787812793595468.
d3 = 21053787812793595469.
Le message chiré :
25967876233197506537, 13324769616062473420,
4067083995440774796, 15335873750405871497,
18818092384507483918, 22565633374253385240
4.4 Déchirement 3
La clé publique est (n, e) = (38418528187951537281949217801, 5). L'un des nombres premiers
qui compose le modulus est p = 188701239274813.
Retrouvez la clé privée, et déchirez le message ci-dessous.
13732714822284920011301570435, 6496030651252994364438015580,
26561308673560068045758981522, 31697794568738883620541514847,
22275744630171780979627444468, 4411101228727954225376
4.5 Déchirement 4
La clé publique est (n, e) = (29961950402435000214455332031185772183148942025143725898858497, 7).
Décryptez le message ci-dessous. Pour cela vous cherchez les nombres premiers qui composent n
en utilisant la fonction ifactor (attention le calcul peut être long).
24975737621200168223081130891842714741163324128224212667090066,
8218031276745420690718022689797588337803163696013100513148147
5 Bibliographie et liens
1.
2.
3.
4.
5.
6.
Cours d'algèbre, Michel Demazure, Cassini, 1997.
Cours de cryptographie, Gilles Zemor, Cassini, 2000.
Cryptographie : théorie et pratique, Douglas Stinson, Vuibert, 2001.
Cryptographie appliquée, Bruce Schneier, Vuibert, 2001.
Introduction à l'algorithmique, Thomas Cormen, Charles Leiserson, Ronald Rivest, Dunod
1994.
Modern computer algebra, Joachim von zur Gathen, Jürgen Gerhard, Cambridge University
Press, 1999.
Cryptanalysis of Short RSA Secret Exponents, Michael Wiener, IEEE Transaction on Information Theory, vol 36, nno 3, mai 1990.
8. Ars Cryptographica, un site très riche fait par un prof de maths suisse pour ses élèves
(http://www.apprendre-en-ligne.net/crypto/menu/index.html).
9. Le handbook de cryptographie en ligne (http://www.cacr.math.uwaterloo.ca/hac/).
10. le générateur de clés RSA à trappes proposé par Claude Crépeau et Alain Slakmon (http:
//crypto.cs.mcgill.ca/~crepeau/RSA/).
7.
9
Téléchargement