L'expression du but : fiche et exercices niveau C1 FLE
Rapport tp RSA
1. Etude et Implémentation de RSAENSA-Tanger3384553129915Encadré par : Pr. S.LAZAARRéalisé par : COHEN AchrafYACOUBOU S. Bouraima<br />Algorithme RSA :<br />Présentation:<br />Le RSA a été inventé par Rivest, Shamir et Adleman en 1978. C’est l’exemple le plus courant de cryptographie asymétrique, toujours considéré comme sûr, avec la technologie actuelle, pour des clés suffisamment grosses (1024, 2048 voire 4096 bits). D’ailleurs le RSA128 (algorithme avec des cl´es de 128 bits), propos´e en 1978 par Rivest, Shamir et Adleman, n’a été “cassé” qu’en 1996, en faisant travailler en parallèle de nombreux ordinateurs sur internet. Mais le concept de chiffrement asymétrique avec une clef publique était légèrement antérieur (1976). L’idée générale était de trouver deux fonctions f et g sur les entiers, telles que fog = Id, et telle que l’on ne puisse pas trouver f, la fonction de décryptage, à partir de g, la fonction de cryptage. L’on peut alors rendre publique la fonction g (ou clef), qui permettra aux autres de crypter le message à envoyer, tout en étant les seuls à connaître f, donc à pouvoir décrypter. On trouvera un expos´e complet sur RSA.<br />Description du protocole :<br />Le but du jeu est bien sûr de pouvoir transmettre un message codé, que seul le récepteur “officiel” puisse décrypter, c’est-`a-dire qui ne puisse pas être décrypté par un tiers qui intercepterait ledit message. Nous appellerons Alice la destinatrice du message, et Bernard l’´emetteur.<br />Alice génère deux gros nombres premiers p et q, ainsi qu’un gros nombre d premier avec le produit w = (p − 1) (q − 1).<br />Alice calcule n = pq et e tel que de Ξ 1[w].<br />Alice diffuse n et e, garde d et oublie w.<br />Bernard crypte un message M par M => Me[n] et envoie le résultat à Alice.<br />Alice décode alors le message crypté par C => Cd[n]<br />Exemple : <br />Voyons ce qui se passe si l’on prend pour les deux nombres p et q les valeurs 11 et 17. <br />On a alors n = 187 et w = (11 − 1) (17 − 1) = 160. <br />Comme : 161 = 7 × 23, on peut prendre e = 7 et d = 23. <br />Alice va rendre public le couple (187, 7).<br />Bernard veut transmettre à Alice un message codé plus petit que n = 187, mettons la date à laquelle ils vont faire une surprise à Cédric (par exemple, le 10), message qui ne doit pas être intercepté par ledit Cédric, bien sûr.<br />Bernard va donc calculer 107 = 187×53475+175, et envoyer le résultat 175 à Alice.<br />Alice va calculer le reste de la division euclidienne de 17523 par 187 :<br />– Elle calcule d’abord 1752 = 30625 = 163×187+144, donc 1752 Ξ144[187].<br />– Ensuite, 1442 = 20736 = 110 × 187 + 166, donc 1754 Ξ 166[187].<br />– Puis, 1662 = 27556 = 147 × 187 + 67 donc 1758 Ξ 67[187].<br />– Et 672 = 4489 = 24 × 187 + 1 donc 17516 Ξ 1[187].<br />– Enfin, 17523 = 17516 × 1754 × 1752 × 175 donc<br />17523 _ 1 × 166 × 144 × 175[187]<br />Or 166 × 144 × 175 = 4183200 = 22370 × 187 + 10.<br />Alice retrouve donc bien le message envoyé, à savoir 10.<br />Implémentation en JAVA :<br /> Dans cette partie nous présentons notre code Java permettant de manipuler les différentes fonctions de l’algorithme RSA, comme le montre le schéma ci-dessous :<br />Le code source détaillé :<br />package gstr.rsa;<br />import java.io.IOException;<br />import java.math.BigInteger;<br />import java.util.Random;<br />import java.util.Scanner;<br />public class rsa {<br />public static void main(String[] args) throws IOException <br />{<br />System.out.print(quot;
Saisir le message :quot;
);<br />Scanner sc = new Scanner(System.in);<br />String M =sc.nextLine();<br />int P, Q, Z, E, D;<br />BigInteger N;<br />//Générer P et Q<br />P=generateP();<br />Q=generateP();<br />//calcul N<br />N=BigInteger.valueOf(P).multiply(BigInteger.valueOf(Q));<br />//calcul Z<br />Z=(P-1)*(Q-1); <br />//recherche E et D<br />E=rechercheE(Z);<br />D=rechercheD(E,Z);<br />System.out.println(quot;
P=quot;
+P);<br />System.out.println(quot;
Q=quot;
+Q);<br />System.out.println(quot;
N=quot;
+N+quot;
et Z=quot;
+Z);<br />System.out.println(quot;
E=quot;
+E);<br />System.out.println(quot;
D=quot;
+D);<br />System.out.println(quot;
Le Message :quot;
+M);<br />byte[] Me=M.getBytes(quot;
ASCIIquot;
);<br />System.out.print(quot;
Le Message en ASCII :quot;
);<br />for(int k=0; k<M.length();k++)<br />{<br />System.out.print(Me[k]+quot;
quot;
);<br />}<br />BigInteger[] c =new BigInteger[M.length()];<br />c=crypte(M,E,N);<br />System.out.print(quot;
Le message Crypté :quot;
);<br />for(int l=0; l<M.length(); l++)<br /> {<br /> System.out.print(c[l]+quot;
quot;
);<br /> <br /> }<br />BigInteger[] dec =new BigInteger[M.length()];<br />dec=decrypte(c,D,N);<br />System.out.print(quot;
Le message Decrypté :quot;
);<br />for(int l=0; l<c.length; l++)<br /> {<br /> System.out.print(dec[l]+quot;
quot;
); <br /> }<br />System.out.print(quot;
Le message en Clair:quot;
);<br />for(int l=0; l<c.length; l++)<br /> {<br />String pa= dec[l].toString();<br />int ii= Integer.parseInt(pa);<br />String aChar = new Character((char)ii).toString();<br />System.out.print(aChar);<br /> }<br />}<br />// la fonction permettant de déchiffrer le message chiffré<br />public static BigInteger[] decrypte(BigInteger c[],int d, BigInteger n) throws IOException<br />{<br />BigInteger[] dec= new BigInteger[c.length];<br />for(int i=0; i<c.length;i++)<br />{<br />dec[i]=(c[i].pow(d)).mod(n);<br />//System.out.println((c[i].pow(d)));<br />}<br />return dec;<br />}<br />// la fonction permettant de chiffrer le message<br />public static BigInteger[] crypte(String ch, int e, BigInteger n) throws IOException<br />{<br />byte[] Me=ch.getBytes(quot;
ASCIIquot;
);<br />BigInteger[] c= new BigInteger[ch.length()];<br />for(int i=0; i<ch.length();i++)<br />{<br />c[i]=(BigInteger.valueOf(Me[i]).pow(e)).mod(n);<br />}<br />return c;<br />}<br />// permet de rechercher le paramètre e<br />public static int rechercheE(int z){<br />int e;<br />for(e=1;e<z;e++)<br />{<br />if(z%e!=0)<br />{<br />break;<br />}<br />}<br />return e;<br />}<br />// permet de rechercher le paramètre d<br />public static int rechercheD(int e, int z){<br /> int d;<br /> for(d=1;d<z;d++)<br /> {<br /> int p=d*e;<br /> if(p%z==1)<br /> {<br /> break;<br /> }<br /> }<br />return d;<br />} <br />// permet de generer les P et Q<br />public static int generateP(){<br />int P;<br />do{<br />P=generate();<br />}<br />while(!isFirst(P) || P<10);<br />return P;<br />}<br />// permet de verfier paire/impaire<br />public static boolean isFirst(int p)<br />{<br />boolean b=true;<br />int i;<br />for(i=2; (i<=p/2) && (p%i!=0);i++);<br />if(p%i==0) b=false;<br />else b=true;<br />return b;<br />}<br />// genere un nombre aléatoire<br />public static int generate()<br />{<br />int p;<br />Random rn = new Random();<br />p=rn.nextInt(200);<br />return p;<br />}<br />}<br />-577215433705Démonstration :<br />D’après le schéma ci-dessus, on retrouve le message chiffré souhaité.<br />Client/serveur RSA :<br />Dans cette partie nous abordons une autre façon de l’utilisation de l’algorithme RSA, il s’agit de deux personnes distantes qui s’échangent des messages cryptés à l’aide de l’algorithme RSA.<br />Pour ce, nous avons crée un programme Java basé sur les Sockets et suivant l’architecture Client/Serveur qui permet de communiquer de façon sécurisée.<br />Les classes sont jointes à ce rapport.<br />Démonstration :<br />-732155477520<br /> ClientServeur<br />Dans cette démo le client a demandé la clé publique du serveur qui la lui a envoyée, ensuite le client a envoyé son message chiffré à l’aide de la clé publique du serveur. A la réception le serveur a déchiffré le message reçu à l’aide de sa clé privée.<br />N.B : à noter que toute l’opération se déroule en temps réel.<br />Conclusion :<br />Ce TP nous a permis de comprendre et de manipuler l’algorithme RSA ; son implémentation en Java a été la partie la plus intéressante car elle constitue la mise en pratique des connaissances acquises durant le cours de la cryptographie. <br />