TD: Cryptage RSA

publicité
TD: Cryptage RSA
1 Position du problème
On propose de réaliser la méthode de cryptage due à Rivest, Shamir et Adleman (dite méthode RSA). Cet
algorithme date de 1977, il repose sur le fait que, si l’on multiplie ensemble deux nombres premiers très grands
(p et q), il est très difficile1 de redécomposer le résultat obtenu (n = p.q) en facteurs premiers (p et q).
La méthode RSA, dite à clef publique, est la suivante2 :
1. à chaque lettre ` de l’alphabet, on affecte un nombre n` compris entre 1 et nmax .
(Si on ne prend que les lettres majuscules non accentuées et le caractère blanc, on a nmax = 27).
`X
max
2. on transforme le texte à transmettre (formé de `max lettres) en un nombre: message =
n` × n`max .
`=1
3. un interlocuteur 1 choisit secrètement deux nombres premiers très grands p1 et q1 congrus3 à 2 modulo 3.
Il publie leur produit (la clef publique): n1 = p1 .q1 . Il garde secrètement le résultat d’un autre calcul (la clef
1 −1)+1
(k1 est forcément un entier).
privée): k1 = 2.(p1 −1).(q
3
La fonction codage de x consiste à calculer une certaine fonction fn1 (x);
la fonction décodage de x consiste à calculer la fonction inverse: fn−1
(x).
1 ,k1
2 −1)+1
.
4. un interlocuteur 2 fait de même avec p2 , q2 , n2 = p2 .q2 et k2 = 2.(p2 −1).(q
3
5. lorsque 1 veut transmettre le message à 2, il envoie: xxxx = fn2 (fn−1
(message)).
1 ,k1
6. lorsque 2 veut décoder xxxx, il calcule fn1 (fk−1
(xxxx))
=
message.
,n
2
2
7. le récepteur décompose le nombre message dans la base nmax et transforme chaque nombre de la décomposition en lettre de l’alphabet pour retrouver le texte.
La fonction codage fni (yyyy) consiste à décomposer yyyy dans la base ni puis à élever chaque terme de la
décomposition au cube modulo ni .
La fonction décodage fn−1
(zzzz) consiste à élever zzzz à la puissance 3.ki modulo ni . Cette procédure
i ,ki
utilise le petit théorème de Fermat généralisé:
- soit m et n deux nombres premiers entre eux (m < n);
- soit Φ(n) la fonction d’Euler donnant le nombre des entiers inférieurs et premiers avec n.
Ici Φ(n) = (p − 1) ∗ (q − 1).
On a alors: mΦ(n) ≡ 1 [n] ⇒ m(p−1).(q−1) ≡ 1 [n] ⇒ ∀k ∈ N, mk.(p−1).(q−1) ≡ 1 [n]
⇒ ∀k ∈ N, mk.(p−1).(q−1)+1 ≡ m [n]
Comme p ≡ q ≡ 2 [3], on a: 2.(p − 1).(q − 1) + 1 ≡ 0 [3] et donc ∃k ∈ N tel que 2.(p − 1).(q − 1) + 1 = 3.k
2 Code avec Mathematica
RSA
Transformation: lettres <-> chiffres
In[1]:= Code[texte ]:=Module[{elements,ii,imax},
elements=ToCharacterCode[texte]; imax=Length[elements];
For[res=0;ii=1,ii<=imax,ii++,res=res+elements[[ii]]*65537^(imax-ii)]; Return[res]];
Decode[nombre ]:=( texte=IntegerDigits[nombre,65537]; FromCharacterCode[texte]);
Code["message"]
Decode[Code["message"]]
1
Historiquement, p était un nombre de 64 chiffres et q un nombre de 65 chiffres. En 1994, le nombre n = p.q
de 129 chiffres (RSA129) a pu être décomposé en p et q grâce à 1600 ordinateurs travaillant en parallèle pendant
deux jours.
2
Les 2 premières étapes sont communes à toutes les méthodes de codage.
3
i.e. dont le reste de la division euclidienne par 3 est 2.
1
ISEN-Brest. Kany.
TD: Cryptage RSA
Out[3]= 8636782494647089498447787918053
Out[4]= message
Clefs de 1 et 2
In[5]:= p1=Prime[30001]
q1=Prime[30002]
Mod[p1,3]
Mod[q1,3]
Out[5]= 350381
Out[6]= 350411
Out[7]= 2
Out[8]= 2
In[9]:= n1=p1*q1
k1=(2*(p1-1)*(q1-1)+1)/3
Out[9]= 122777356591
Out[10]= 81851103867
In[11]:= p2=Prime[30003]
q2=Prime[30004]
Mod[p2,3]
Mod[q2,3]
Out[11]= 350423
Out[12]= 350429
Out[13]= 2
Out[14]= 2
In[15]:= n2=p2*q2
k2=(2*(p2-1)*(q2-1)+1)/3
Out[15]= 122798381467
Out[16]= 81865120411
Codage
In[17]:= ListeEnNombre[liste ,cle ]:=Module[{NbreTermes,ii,res},
NbreTermes=Length[liste];
For[res=0;ii=1,ii<=NbreTermes,ii++,res+=liste[[ii]]*cle^(ii-1)]; Return[res];];
Codage[liste ]:=Module[{nombre,cle},
nombre=liste[[1]];cle=liste[[2]];Return[Mod[nombre^3,cle]]];
In[19]:= (*Pour insersion de la clef entre chaque element de la liste*)
Sow[expr ,object ]:=Insert[expr,object,List/@Range[2,Length[expr]+1]]
RSA[nombre ,ClePublique ]:=Module[{ListeCodee,ListeDecodee,res},
2
ISEN-Brest. Kany.
TD: Cryptage RSA
ListeDecodee=IntegerDigits[nombre,ClePublique];
ListeDecodee=Partition[Sow[ListeDecodee,ClePublique],2];
ListeCodee=Map[Codage,ListeDecodee];
Return[ListeEnNombre[ListeCodee,ClePublique]];];
MessageCode=RSA[Code["Message"],n1]
Out[22]= 683863267296776668652927526278887
Decodage
In[23]:= expomodulo[xx ,nn ,mm ]:=Module[{liste,ii,imax,res,puissance},
puissance=Mod[xx,mm]; liste=IntegerDigits[nn,2]; imax=Length[liste];
If[liste[[imax]]==1,res=xx,res=1];
For[ii=imax-1,ii>=1,ii--,
puissance=Mod[puissance^2,mm]; If[liste[[ii]]==1,res=Mod[res*puissance,mm];];];
Return[res];]
Decodage[liste ]:=Module[{nombre,ClePrivee,ClePublique},
nombre=liste[[1]];ClePrivee=liste[[2]][[1]];ClePublique=liste[[2]][[2]];
Return[expomodulo[nombre,ClePrivee,ClePublique]]];
ASR[nombre ,ClePrivee ,ClePublique ]:=Module[{ListeCodee,ListeDecodee,res},
ListeCodee=IntegerDigits[nombre,ClePublique];
ListeCodee=Partition[Sow[ListeCodee,{ClePrivee,ClePublique}],2];
ListeDecodee=Map[Decodage,ListeCodee];
Return[ListeEnNombre[ListeDecodee,ClePublique]];];
ASR[MessageCode,k1,n1]
Out[26]= 6101249171578647385225561440965
1 envoie un message 2
In[27]:= Code["Bonjour, ca va ?"]
ASR[Code["Bonjour, ca va ?"],k1,n1]
MessageEnvoye=RSA[ASR[Code["Bonjour, ca va ?"],k1,n1],n2]
Out[27]= 116641592712282001463149217660028982581610315105012093918877189000477672773
Out[28]= 159071632319608592115103484642891131233449708039690962730108017175548532624434
Out[29]= 351613662903029463412718813642207235213337678647855147225107131666234478270218
2 décode le message de 1
In[30]:= ASR[MessageEnvoye,k2,n2]
MessageRecu=RSA[ASR[MessageEnvoye,k2,n2],n1]
Decode[MessageRecu]
Out[30]= 159071632319608592115103484642891131233449708039690962730108017175548532624434
Out[31]= 116641592712282001463149217660028982581610315105012093918877189000477672773
Out[32]= Bonjour, ca va ?
3 connait n1 et n2 mais pas k2, il ne peut pas décoder. Exemple:
In[33]:= p3=Prime[30008]
q3=Prime[30009]
Mod[p3,3]
3
ISEN-Brest. Kany.
TD: Cryptage RSA
Mod[q3,3]
k3=(2*(p3-1)*(q3-1)+1)/3
Out[33]= 350447
Out[34]= 350453
Out[35]= 2
Out[36]= 2
Out[37]= 81876334395
In[38]:= Decode[RSA[ASR[MessageEnvoye,k3,n2],n1]]
Out[38]= ΛûDû? ⊂ û!µû > û?GûpûOX ûê?ûë ← ûQ?ûl&ûË∃û ∪ +û]9û??û?
3 Code avec Python
Téléchargez la bibliothèque PyPrime à l’adresse:
https://pypi.python.org/pypi/pyprimes/
et installez le package pyprimes-0.1.1a.tar.gz à l’aide de WinPython Control Panel
suivi de Install packages).
# -*- coding: utf-8 -*import random
import pyprimes
import math
4
(Add packages
Téléchargement