Cryptographie - smb-personnel.univ-reunion.fr
Cryptographie - smb-personnel.univ-reunion.fr
Cryptographie - smb-personnel.univ-reunion.fr
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Sécurité informatique M1 Informatique<br />
1 <strong>Cryptographie</strong> classique<br />
<strong>Cryptographie</strong><br />
Chif<strong>fr</strong>e de César (substitution monoalphabétique)<br />
Écrivez en Python un programme permettant de crypter/décrypter des messages au moyen du<br />
chif<strong>fr</strong>e de César. L’utilisateur doit pouvoir choisir le décalage dans l’alphabet (ce décalage vaut 3<br />
dans le chif<strong>fr</strong>e de César original).<br />
Chif<strong>fr</strong>e de Vigenère (substitution polyalphabétique)<br />
Écrivez en Python un programme permettant de crypter/décrypter des messages au moyen<br />
du chif<strong>fr</strong>e de Vigenère. L’utilisateur doit pouvoir choisir sa clé. Trouvez une solution pour ne pas<br />
avoir à coder la table (le contenu d’une case de la table doit être calculé au besoin).<br />
Chif<strong>fr</strong>e de Hill (substitution polyalphabétique)<br />
Écrivez en Python un programme permettant de crypter/décrypter des messages au moyen du<br />
chif<strong>fr</strong>e de Hill dans le cas où m = 2. L’utilisateur doit pouvoir choisir les coefficients a, b, c et d<br />
des combinaisons linéaires.<br />
Transposition rectangulaire<br />
Écrivez en Python un programme permettant de crypter/décrypter des messages au moyen<br />
d’une transposition rectangulaire. L’utilisateur doit pouvoir choisir les nombres de lignes et de<br />
colonnes de la matrice ainsi que la permutation (donnée sous la forme d’une chaîne de caractères<br />
ne comportant pas deux fois le même caractère).<br />
Chif<strong>fr</strong>e de Delastelle (substitution + transposition)<br />
Écrivez en Python un programme permettant de crypter/décrypter des messages au moyen du<br />
chif<strong>fr</strong>e de Delastelle.<br />
2 DES<br />
On considère les éléments suivants donnés en notation hexadécimale :<br />
K = 0123456789ABCDEF, la clé<br />
M = 23456789ABCDEF01, le texte en clair.<br />
Les conversions entre écritures hexadécimales et binaires se font simplement en utilisant le tableau<br />
de correspondances suivant :<br />
héxa 0 1 2 3 4 5 6 7<br />
bin 0000 0001 0010 0011 0100 0101 0110 0111<br />
héxa 8 9 A B C D E F<br />
bin 1000 1001 1010 1011 1100 1101 1110 1111<br />
1
Sécurité informatique M1 Informatique<br />
Fig. 1 – Les 16 rondes du DES, où IP est la permutation initiale, FP la permutation finale, F la<br />
fonction de Feistel et ⊕ le ou exclusif (xor).<br />
Par exemple, 23 en hexadécimal correspond à<br />
����<br />
0010 0011<br />
����<br />
en binaire.<br />
En utilisant l’algorithme du DES, on demande de :<br />
1. calculer les deux sous-blocs de 32 bits L0 et R0 (figures 1 et 2) ;<br />
2. appliquer l’expansion E sur R0 pour obtenir E(R0) (figures 3 et 4) ;<br />
3. dériver la première sous-clé K1 (figures 6, 7 et 8) ; la rotation à gauche est de 1 bit ;<br />
4. calculer A = E(R0) ⊕ K1, où ⊕ est le ou exclusif (xor) ;<br />
2<br />
5. grouper les bits de A en blocs de 6 éléments et calculer les valeurs fournies par les S-Box S1,<br />
. . . , S8 correspondantes (figures 3 et 9) ;<br />
6. concaténer les résultats obtenus au (5) pour obtenir la suite B de 32 bits ;<br />
7. appliquer la permutation P à B pour obtenir P (B) (figures 3 et 5) ;<br />
8. calculer R1 = P (B) ⊕ L0,<br />
9. écrire en hexadécimal le bloc chif<strong>fr</strong>é L1R1 obtenu (figure 1).<br />
Vérifiez vos réponses en implémentant l’algorithme du DES en Python. Les rotations pour le<br />
calcul des sous-clés (figure 6) sont données à la figure 10.<br />
2<br />
3
Sécurité informatique M1 Informatique<br />
58 50 42 34 26 18 10 2<br />
60 52 44 36 28 20 12 4<br />
62 54 46 38 30 22 14 6<br />
64 56 48 40 32 24 16 8<br />
57 49 41 33 25 17 9 1<br />
59 51 43 35 27 19 11 3<br />
61 53 45 37 29 21 13 5<br />
63 55 47 39 31 23 15 7<br />
Fig. 2 – Permutation initiale IP. Entrée : 64 bits. Sortie : 64 bits. Le 1er bit de la sortie est obtenu<br />
en prenant le 58ème bit de l’entrée, le second en prenant le 50ème bit de l’entrée, . . . , le dernier<br />
en prenant le 7ème bit de l’entrée.<br />
Fig. 3 – La fonction de Feistel F , où E est l’expansion, ⊕ le ou exclusif (xor), les S1, . . . , S8 sont<br />
les S-Box et P est la permutation.<br />
32 1 2 3 4 5<br />
4 5 6 7 8 9<br />
8 9 10 11 12 13<br />
12 13 14 15 16 17<br />
16 17 18 19 20 21<br />
20 21 22 23 24 25<br />
24 25 26 27 28 29<br />
28 29 30 31 32 1<br />
Fig. 4 – Expansion E. Entrée : 32 bits. Sortie : 48 bits. Le 1er bit de la sortie est obtenu en prenant<br />
le 32ème bit de l’entrée, le second en prenant le 1er bit de l’entrée, . . . , le dernier en prenant le<br />
1er bit de l’entrée.<br />
3
Sécurité informatique M1 Informatique<br />
16 7 20 21 29 12 28 17<br />
1 15 23 26 5 18 31 10<br />
2 8 24 14 32 27 3 9<br />
19 13 30 6 22 11 4 25<br />
Fig. 5 – Permutation P . Entrée : 32 bits. Sortie : 32 bits. Le 1er bit de la sortie est obtenu en<br />
prenant le 16ème bit de l’entrée, le second en prenant le 7ème bit de l’entrée, . . . , le dernier en<br />
prenant le 25ème bit de l’entrée.<br />
Fig. 6 – Calcul des sous-clés du DES. La notation
Sécurité informatique M1 Informatique<br />
S1<br />
x0000x x0001x x0010x x0011x x0100x x0101x x0110x x0111x x1000x x1001x x1010x x1011x x1100x x1101x x1110x x1111x<br />
0yyyy0 14 4 13 1 2 15 11 8 3 10 6 12 5 9 0 7<br />
0yyyy1 0 15 7 4 14 2 13 1 10 6 12 11 9 5 3 8<br />
1yyyy0 4 1 14 8 13 6 2 11 15 12 9 7 3 10 5 0<br />
1yyyy1 15 12 8 2 4 9 1 7 5 11 3 14 10 0 6 13<br />
S2<br />
x0000x x0001x x0010x x0011x x0100x x0101x x0110x x0111x x1000x x1001x x1010x x1011x x1100x x1101x x1110x x1111x<br />
0yyyy0 15 1 8 14 6 11 3 4 9 7 2 13 12 0 5 10<br />
0yyyy1 3 13 4 7 15 2 8 14 12 0 1 10 6 9 11 5<br />
1yyyy0 0 14 7 11 10 4 13 1 5 8 12 6 9 3 2 15<br />
1yyyy1 13 8 10 1 3 15 4 2 11 6 7 12 0 5 14 9<br />
S3<br />
x0000x x0001x x0010x x0011x x0100x x0101x x0110x x0111x x1000x x1001x x1010x x1011x x1100x x1101x x1110x x1111x<br />
0yyyy0 10 0 9 14 6 3 15 5 1 13 12 7 11 4 2 8<br />
0yyyy1 13 7 0 9 3 4 6 10 2 8 5 14 12 11 15 1<br />
1yyyy0 13 6 4 9 8 15 3 0 11 1 2 12 5 10 14 7<br />
1yyyy1 1 10 13 0 6 9 8 7 4 15 14 3 11 5 2 12<br />
S4<br />
x0000x x0001x x0010x x0011x x0100x x0101x x0110x x0111x x1000x x1001x x1010x x1011x x1100x x1101x x1110x x1111x<br />
0yyyy0 7 13 14 3 0 6 9 10 1 2 8 5 11 12 4 15<br />
0yyyy1 13 8 11 5 6 15 0 3 4 7 2 12 1 10 14 9<br />
1yyyy0 10 6 9 0 12 11 7 13 15 1 3 14 5 2 8 4<br />
1yyyy1 3 15 0 6 10 1 13 8 9 4 5 11 12 7 2 14<br />
S5<br />
x0000x x0001x x0010x x0011x x0100x x0101x x0110x x0111x x1000x x1001x x1010x x1011x x1100x x1101x x1110x x1111x<br />
0yyyy0 2 12 4 1 7 10 11 6 8 5 3 15 13 0 14 9<br />
0yyyy1 14 11 2 12 4 7 13 1 5 0 15 10 3 9 8 6<br />
1yyyy0 4 2 1 11 10 13 7 8 15 9 12 5 6 3 0 14<br />
1yyyy1 11 8 12 7 1 14 2 13 6 15 0 9 10 4 5 3<br />
5<br />
S6<br />
x0000x x0001x x0010x x0011x x0100x x0101x x0110x x0111x x1000x x1001x x1010x x1011x x1100x x1101x x1110x x1111x<br />
0yyyy0 12 1 10 15 9 2 6 8 0 13 3 4 14 7 5 11<br />
0yyyy1 10 15 4 2 7 12 9 5 6 1 13 14 0 11 3 8<br />
1yyyy0 9 14 15 5 2 8 12 3 7 0 4 10 1 13 11 6<br />
1yyyy1 4 3 2 12 9 5 15 10 11 14 1 7 6 0 8 13<br />
S7<br />
x0000x x0001x x0010x x0011x x0100x x0101x x0110x x0111x x1000x x1001x x1010x x1011x x1100x x1101x x1110x x1111x<br />
0yyyy0 4 11 2 14 15 0 8 13 3 12 9 7 5 10 6 1<br />
0yyyy1 13 0 11 7 4 9 1 10 14 3 5 12 2 15 8 6<br />
1yyyy0 1 4 11 13 12 3 7 14 10 15 6 8 0 5 9 2<br />
1yyyy1 6 11 13 8 1 4 10 7 9 5 0 15 14 2 3 12<br />
S8<br />
x0000x x0001x x0010x x0011x x0100x x0101x x0110x x0111x x1000x x1001x x1010x x1011x x1100x x1101x x1110x x1111x<br />
0yyyy0 13 2 8 4 6 15 11 1 10 9 3 14 5 0 12 7<br />
0yyyy1 1 15 13 8 10 3 7 4 12 5 6 11 0 14 9 2<br />
1yyyy0 7 11 4 1 9 12 14 2 0 6 10 13 15 3 5 8<br />
1yyyy1 2 1 14 7 4 10 8 13 15 12 9 0 3 5 6 11<br />
Fig. 9 – Les 8 S-Box. Entrée : 6 bits. Sortie : 4 bits. Par exemple, pour S5 avec l’entrée 011011, on regarde la case ligne 0yyyy1, colonne x1101x, et<br />
on obtient comme sortie 9 i.e. 1001.
Sécurité informatique M1 Informatique<br />
ronde 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16<br />
rotations 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1<br />
3 <strong>Cryptographie</strong> RSA<br />
Calculs à la main<br />
On choisit p = 5 et q = 11.<br />
1. Combien vaut n ?<br />
2. Combien vaut z ?<br />
Fig. 10 – Les rotations pour le calcul des sous-clés.<br />
3. On choisit e = 3 : est-ce correct ? Pourquoi ?<br />
4. Donnez une valeur correcte pour d.<br />
5. Cryptez le message M = 5.<br />
Un sujet d’examen<br />
Résolvez l’exercice 1 du sujet d’examen de 2009.<br />
Un petit (?) programme<br />
Le but de cet exercice est d’écrire un programme Python permettant de créer des espions<br />
s’envoyant des messages cryptés au moyen de l’algorithme RSA. Chaque espion possède une clé<br />
publique et une clé privée qui sont fabriquées à la création de l’espion. Le programme doit proposer<br />
le menu suivant à l’utilisateur et exécuter l’action correspondant à son choix :<br />
1) Creer un espion<br />
2) Afficher la liste des espions<br />
3) Envoyer un message<br />
4) Quitter le programme<br />
Nombres premiers<br />
Écrivez le module Eratosthene permettant de gérer les nombres premiers. Vous prévoirez les<br />
éléments suivants.<br />
– La liste crible qui sert à stocker les nombres premiers qui sont calculés pendant l’exécution<br />
du programme.<br />
– La fonction estPremier prenant en argument un entier et renvoyant true si et seulement<br />
si l’entier est premier. Vous écrirez cette méthode en utilisant la technique du crible d’Eratosthène.<br />
– La fonction get prenant en argument une borne (un entier) et renvoyant un nombre premier<br />
strictement plus petit que cette borne et choisi au hasard.<br />
Modulo<br />
Écrivez le module Modulo permettant de gérer des calculs dans Z/nZ. Vous prévoirez les<br />
éléments suivants.<br />
– La fonction inverse prenant en argument deux entiers a et n et renvoyant l’inverse de a<br />
modulo n.<br />
– La fonction puissance prenant en argument trois entiers a, b et n et renvoyant le nombre :<br />
(a à la puissance b) modulo n.<br />
6
Sécurité informatique M1 Informatique<br />
Schéma de remplissage<br />
Écrivez le module OAEP permettant de gérer le schéma de remplissage précédent le cryptage.<br />
Vous prévoirez :<br />
– les fonctions G et H calculant un résumé (digest) de leur argument, par exemple en utilisant<br />
SHA1 ou MD5 (module hashlib de Python) ;<br />
– la fonction pad prenant en argument un message en clair m et renvoyant les nombres X et Y<br />
calculés par le schéma de remplissage OAEP ; vous vous arrangerez pour que ces nombres<br />
soient plus petits que l’entier n du cryptage RSA ;<br />
– la fonction unpad prenant en argument des nombres X et Y (supposés calculés par OAEP) et<br />
renvoyant le message m correspondant.<br />
Les espions<br />
Écrivez la classe Espion permettant de gérer les espions créés par l’utilisateur. Vous prévoirez<br />
les éléments suivants.<br />
– Les attributs p, q, n, phi_n, e et d (des entiers) correspondant aux nombres du même nom<br />
dans l’algorithme RSA.<br />
– L’attribut nom (une chaîne de caractères) permettant de stocker le nom de l’espion.<br />
– Un constructeur dont les arguments sont : une chaîne de caractères permettant d’initialiser le<br />
nom, un entier permettant d’initialiser p et un entier permettant d’initialiser q. Ce constructeur<br />
devra calculer la valeur de n et de phi_n, choisir au hasard une valeur convenable pour<br />
e puis calculer la valeur de d.<br />
– Les méthodes get_e, get_n et getNom qui renvoient respectivement la valeur de l’attribut<br />
e, n et nom.<br />
– La méthode crypter prenant en argument un message (une chaîne de caractères) et deux<br />
entiers e et n et qui crypte le message en utilisant la clé publique (e,n).<br />
– La méthode decrypter prenant en argument un message crypté, qui décrypte le message<br />
en utilisant la clé privée (d,n) (attributs définis ci dessus) et qui renvoie une chaîne de<br />
caractères correspondant au message en clair.<br />
– La méthode __str__ qui renvoie une chaîne de caractères de la forme nom(e,n) (où nom, e<br />
et n sont remplacés par leur valeur).<br />
Le programme principal<br />
Le programme principal devra afficher le menu, demander à l’utilisateur quel est son choix,<br />
effectuer l’opération correspondante puis recommencer, ceci tant que l’utilisateur ne demande pas<br />
de quitter le programme. Le programme devra gérer la liste des espions créés par l’utilisateur.<br />
– Création d’un espion : le programme doit demander à l’utilisateur le nom de l’espion ainsi<br />
que deux entiers premiers p et q, vérifier que p et q sont bien premiers (si ce n’est pas le cas<br />
il faut redemander ces valeurs), créer un espion à partir de ces données et ajouter l’espion<br />
créé à la liste des espions.<br />
– Afficher la liste des espions : le programme doit afficher la liste des espions qui ont été<br />
créés par l’utilisateur.<br />
– Envoyer un message : le programme doit demander à l’utilisateur le nom de l’espion<br />
expéditeur, le nom de l’espion destinataire (si ces noms n’existent pas il faut les redemander),<br />
le contenu du message, afficher le message crypté par l’expéditeur et afficher le résultat du<br />
décryptage (par le destinataire) du message crypté par l’expéditeur (ce message décrypté<br />
doit correspondre au message en clair original lorsque tout va bien). Par exemple :<br />
Nom de l’expediteur: Austin<br />
Nom du destinataire: Felicity<br />
Message a envoyer: Yeah baby, yeah!<br />
Austin envoie le message crypte suivant a Felicity: 37 57 95 25 95 37 57<br />
151 0 0 95 95 95 37 95 95 94 25 1 151 0 0 94 25 95 25 95 37 57 151 0 1<br />
Felicity decrypte le message de Austin: Yeah baby, yeah!<br />
7