TP1

publicité
TP : Cryptographie
Important : Un rapport doit être rendu au plus tard 10 jours après le TP.
Objectif :
Comprendre le mécanisme de chiffrement des mots de passe sous Linux
Mise en œuvre d’un algorithme de chiffrement basé sur le « OU exclusif »
Apprendre à utiliser la boite à outil cryptographique « openssl »
Comprendre la mise en œuvre des algorithmes de chiffrement, des signatures numériques et les certificats
Génération des clefs de l’algorithme RSA avec l’utilisation de la bibliothèque GMP
Pré-requis :
Programmation C
Algorithmes de cryptographie
0- Introduction (OpenSSL)
OpenSSL est une boite à outils cryptographiques qui offre :
a) une bibliothèque de programmation en C permettant de réaliser des applications client/serveur sécurisées s’appuyant
sur SSL/TLS.
b) une commande en ligne (openssl) permettant
– la création de clefs RSA, DSA (signature) ;
– la création de certificats X509 ;
– le calcul d’empreintes (MD5, SHA, RIPEMD160, . . . ) ;
– le chiffrement et déchiffrement (DES, IDEA, RC2, RC4, Blowfish, . . . ) ;
– la réalisation de tests de clients et serveurs SSL/TLS ;
– la signature et le chiffrement de courriers (S/MIME).
Pour connaître toutes les fonctionnalités de openSSL : « man openssl »
La syntaxe générale de la commande openssl est : $ openssl <commande> <options>
I- Sécurité du système Unix/Linux
Fichiers de mots de passe
Le fichier « passwd » : se trouve dans /etc/passwd contient des informations sur les utilisateurs. Il est, par défaut,
lisible par tous les utilisateurs.
man 5 passwd
Le fichier « shadow » : se trouve dans /etc/shadow contient des informations sur les mots de passe des utilisateurs. Il
est, par défaut, lisible uniquement par l'administrateur.
man 5 shadow
Exercice 1 :
Q 1. Créez un utilisateur user1 avec un mot de passe quelconque en utilisant la commande « adduser ».
man 8 adduser
Q 2. Identifiez le champ contenant le mot de passe de l'utilisateur.
Remarque : Le mot de passe peut être chiffré avec DES ou avec MD5. Si le champ du mot de passe de l'utilisateur
commence avec $1$, le mot de passe est chiffré avec MD5, sinon il est chiffré avec DES. Le sel se trouve entre le
deuxième $ et le troisième $. Le mot de passe chiffré se trouve après le troisième $.
Syntaxe :
openssl passwd [options]
EIOC-3
TP Sécurité
A. RACHEDI
- 1/6
où les options possibles sont :
-crypt : pour l'algorithme standard de chiffrement (DES)
-1 : pour un chiffrement basé sur MD5
-salt sel : pour ajouter le sel
Q 3. Obtenez le champ contenant le mot de passe en utilisant openssl.
Q 4. Changez le mot de passe de l'utilisateur user1 et ne tapez que quatre lettres minuscules.
Faites un programme qui prend en entrée le champ contenant le mot de passe et qui retrouve le mot de passe de
l'utilisateur.
II – Cryptographie classique
L’algorithme de chiffrement le plus rapide est basé sur le « OU exclusif ». Implémentez cet algorithme en langage C
Télécharger le fichier « xor.c » et compléter ce dernier (en particulier les partie /* A COMPLETER */).
-Tester ce programme comme suit : Chiffrer n’importe quel fichier avec une clef secrète et ensuite déchiffrer ce fichier avec le
même programme xor.
III – Cryptographie moderne
III-2- Chiffrement symétrique avec openSSL
C’est la commande « enc » qui permet de chiffrer/déchiffrer avec openssl. ($openssl enc <options>)
Pour chiffrer le fichier « toto » avec l’algorithme DES en mode CBC, avec une clef générée par mot de passe, le
cryptogramme est enregistré dans le fichier « toto.chiffre », on utilise la commande :
$ openssl enc −des−cbc −in toto −out toto.c h i f f r e
Pour déchiffrer le même fichier, il suffit d’ajouter l’argument « -d »
Codage en base64
Définition : Base64 est un codage utilisant 65 caractères imprimables (les 26 lettres majuscules, les 26 lettres
minuscules, les 10 chiffres, le caractère +, le caractère / et le caractère spécial =). Base64 permet d'échanger des
données en réduisant les problèmes d'encodage des caractères spéciaux.
Syntaxe : Pour encoder en base64, on utilise : openssl enc -base64 -in fichier
Pour décoder de la base64, on utilise : openssl enc -base64 -d -in fichier
Chiffrement avec mot de passe
Exercice 1 :
Q 1. Chiffrez le fichier de votre choix avec les algorithmes DES et BlowFish en mode CBC de votre choix dans le
mode de votre choix, puis déchiffrez-le.
Q 2. Comparez les tailles des fichiers clairs et chiffrés. Donnez une explication sur la différence de ces tailles.
Q 3. Quelle est la différence entre les deux modes de chiffrement CBC et OFB ? Chiffrer le même fichier avec le
mode OFB, ensuite comparer les deux cryptogrammes.
Exercice 2 :
Le fichier « cryprogramme-1 » a été chiffré avec l’algorithme d’AES en mode CBC, la clef de 128 bits ayant été
obtenue par mot de passe.
Q 1. Le mot de passe codé en base 64 est dHBjcnlwdG9jMwo=. A l’aide de la commande openssl appropriée,
décodez le mot de passe.
Q 2. Déchiffrez ensuite le fichier « cryptogramme-1 ».
Chiffrement avec clef explicite
Pour chiffrer le fichier « toto » avec une clé explicite, il faut utiliser les options -K et -iv
-K (K majuscule) suivi de la clé exprimée en hexadécimal ;
-iv (iv en minuscules) suivi du vecteur d'initialisation exprimé en hexadécimal.
L'exemple qui suit montre la commande pour chiffrer « toto » avec Blowfish en mode CBC avec un vecteur
d'initialisation de 64 bits exprimé par 16 chiffres hexa, et une clé de 128 bits exprimée par 32 chiffres hexa.
$openssl enc -bf-cbc -in toto -out toto.chiffre \ -iv 0123456789ABCDEF \ -K 0123456789ABCDEF0123456789ABCDEF
EIOC-3
TP Sécurité
A. RACHEDI
- 2/6
Exercice 3 :
Q 1. Chiffrez le fichier « Fclair » avec l’algorithme Blowfish en mode OFB, en utilisant le vecteur d'initialisation
(option -iv) et la clef (option -K) de votre choix pour obtenir le fichier cryptogram1.
Déchiffrez ensuite le cryptogramme obtenu.
Exercice 4 :
Q 1. Générer une clef aléatoire de 56 bits pour l’utiliser dans l’algorithme DES à l’aide de la commande « openssl rand
<option> ». Sauvegarder cette clef dans fichier nommé « clef_des ».
Q 2. Chiffrer un fichier « toto » avec l’algorithme DES et la clef aléatoire « clef_des ». Déchiffrer le cryptogramme avec la même
clef pour vérifier le bon fonctionnement de ce processus.
Q 3. Utiliser l’empreinte numérique du fichier « toto » à l’aide de l’algorithme MD5 avant et après le processus de chiffrement et
de déchiffrement
Le bourrage (padding)
Lorsque la taille de la donnée n'est pas un multiple de la taille d'un bloc, il est nécessaire de compléter le dernier bloc
avec quelques bits complémentaires : c'est le bourrage (ou padding).
Une façon de remplir, définie dans le RFC2040, consiste à compléter le dernier bloc par autant d'octets que nécessaire,
chaque octet ayant pour valeur le nombre d'octets ajoutés.
S'il se trouve que la taille de la donnée à chiffrer est un multiple de la taille d'un bloc, on ajoute un bloc entier dont
chaque octet a pour valeur la taille en octet d'un bloc.
Exercice 5 :
En chiffrant des fichiers de taille différentes, avec l’algorithme Blowfish (blocs de 64 bits) avec une clef et un vecteur
d'initialisation fournis dans la ligne de commande, observez la taille des chiffrés obtenus.
Lorsqu'on déchiffre un cryptogramme avec openssl, les octets ajoutés lors du bourrage sont supprimés. Avec l'option nopad utilisée dans la ligne de commande de déchiffrement, ces octets ne sont pas supprimés.
Exercice 6 :
En chiffrant des fichiers de taille différentes, avec l’algorithme Blowfish (blocs de 64 bits) avec une clef et un vecteur
d'initialisation fournis dans la ligne de commande, et en les déchiffrant avec l'option -nopad, observez les octets de
bourrage. (Attention, les octets de bourrage ne correspondent pas à des caractères imprimables. Il vous faudra utiliser
hexedit ou xxd pour visualiser le contenu du fichier déchiffré en hexadécimal.)
C'est cette façon de bourrer le dernier bloc qui permet de contrôler que le déchiffrement s'est bien déroulé. En effet, si
après déchiffrement le dernier bloc clair ne se termine pas par n octets identiques valant n, alors on peut en déduire au
moins l'une des causes suivantes :
1.
2.
3.
4.
la clef utilisée lors du déchiffrement est incorrecte,
le vecteur d'initialisation est incorrect,
le dernier bloc chiffré est erroné,
en mode CBC, l'avant dernier bloc est erroné.
Exercice 7 :
Chiffrez avec le système Blowfish en mode CBC et en précisant clef et vecteur d'initialisation dans la ligne de
commande, un fichier de façon à obtenir un cryptogramme de deux blocs.
Puis, vérifiez chacune des quatre causes d'erreur mentionnées ci-dessus.
Vérifiez aussi qu'avec l'option -nopad, openssl n'effectue pas le contrôle de bourrage.
IV- Cryptographie asymétrique
Génération des clefs RSA
Syntaxe : La génération de clefs se fait en utilisant : openssl genrsa -out clef-privée taille
EIOC-3
TP Sécurité
A. RACHEDI
- 3/6
Exercice 1 :
Q 1. Créez une clef privée RSA mySmall.pem de 50 bits.
Syntaxe : Pour obtenir des informations sur une clef, on utilise : openssl rsa -in clef -text -noout
Q 2. Affichez des informations sur la clef privée que vous avez générée.
Q 3. Faut-il conserver la clef privée en clair ? Est-ce que votre clef privée est sauvegardée en clair ?
Syntaxe : Pour ne pas sauvegarder la clef privée en clair, on peut utiliser un algorithme de chiffrement symétrique :
openssl genrsa -des3 -out clef-privée taille
Q 4. Créez une clef privée private1.pem de 1024 bits, sans chiffrement. Créez une clef privée private2.pem de 1024
bits, avec chiffrement.
Q 5. Récupérez les informations sur chacune de ces deux clefs.
Syntaxe : Pour récupérer la clef publique associée à une clef, on utilise :
openssl rsa -in clef-privée -pubout -out clef-publique
Q 6. Créez la clef publique associée à chaque clef privée.
Q 7. Faut-il conserver la clef publique en clair ? Est-ce que votre clef publique est sauvegardée en clair ?
Syntaxe : Pour afficher des informations sur une clef publique, il faut utiliser l'option -pubin pour indiquer que le
fichier d'entrée comprend seulement des informations publiques.
Q 8. Récupérez des informations sur les deux clefs publiques.
Chiffrement et déchiffrement avec RSA
Syntaxe : Pour chiffrer avec une clef publique RSA, on utilise :
openssl rsautl -encrypt -in fichier-clair -inkey clef-publique -pubin -out fichier-chiffré
Pour déchiffrer, on utilise l'option -decrypt.
Q 9. Chiffrez et déchiffrez n’importe quel petit fichier.
Q 10. Chiffrez un gros fichier. Que se passe-t-il ? Pourquoi ?
Q 11. Demandez à votre binôme sa clef publique. Chiffrez un court message avec sa clef publique. Transmettez-le lui,
et demandez-lui de le déchiffrer.
Syntaxe : Pour chiffrer avec DES, on utilise : openssl enc -des -in fichier-clair -out fichier-chiffré
Pour déchiffrer avec DES, on utilise : openssl enc -des -d -in fichier-chiffré -out fichier-clair
Q 12. Demandez à votre binôme sa clef publique. Chiffrez un long message avec un algorithme de chiffrement
symétrique (comme DES), en utilisant un mot de passe. Chiffrez le mot de passe avec la clef publique de votre
binôme. Transmettez à votre binôme le mot de passe chiffré et le message chiffré. Demandez-lui de déchiffrer le
message.
Signatures numérique
Syntaxe : Pour hacher un fichier, on utilise : openssl dgst -md5 -out haché fichier
Syntaxe : Pour signer un haché, on utilise : openssl rsautl -sign -in haché -inkey clef -out signature
Q 13. Faut-il utiliser la clef publique ou la clef privée pour une signature ?
Syntaxe : Pour vérifier une signature, on utilise :
openssl rsautl -verify -in signature -pubin -inkey clef-publique -out haché2
Q 14. Signez un message.
Q 15. Vérifiez sa signature. Vous pourrez utiliser l'outil diff.
Q 16. Créez trois messages. Signez ces trois messages. Modifiez-en un ou deux légèrement.
Transmettez à votre binôme les messages (éventuellement modifiés) ainsi que les signatures correspondantes.
Demandez-lui de déterminer quels sont les messages qui ont été modifiés.
Certificats numériques
Création de certificats
Syntaxe : Pour demander un certificat, il faut créer une requête de la manière suivante :
openssl req -new -key clef -out requête
Remarque : la clef doit être suffisamment grande pour pouvoir signer le certificat. Une clef de 1024 bits convient
généralement.
Q 17. Créer une requête de certificat appelée user-request.pem concernant une entité appelée user. Cette requête est en
attente de signature par une autorité de certification.
Syntaxe : Pour visualiser une requête de certificat ou un certificat, on utilise : openssl x509 -in certificat -text -noout
Q 18. Visualiser le contenu de votre requête de certificat.
Q 19. Créer une paire de clefs pour l'autorité de certification. Créer une requête de certificat nommée ca-request.pem
concernant l'entité de certification appelée CA.
EIOC-3
TP Sécurité
A. RACHEDI
- 4/6
Syntaxe : Pour auto-signer une requête de certificat, on utilise :
openssl x509 -req -in requête -signkey clef-privee -out certificat
Q 20. Autosigner la requête de certificat de CA dans un certificat nommé ca-certificat.pem.
Q 21. Visualiser le certificat ca-certificat.pem.
Syntaxe : Pour signer une requête de certificat, on utilise :
openssl x509 -days duree -CAserial serial -CA certificat -CAkey clef -in requête -req -out certificat
Le fichier serial contient un nombre enregistré en hexadécimal (c'est-à-dire un nombre pair de chiffres hexadécimaux).
Q 22. Signer la requête de certificat user-request.pem pour produire un certificat usercertificat.pem.
Syntaxe : Pour vérifier un certificat, on utilise : openssl verify -CAfile ca-certificat certificat
Q 23. Vérifier le certificat user-certificat.pem.
Q 24. Modifier le contenu du certificat user-certificat.pem et tentez de le vérifier.
Fabrication des clefs RSA avec l’utilisation de la bibliothèque GMP
Le but de cette partie est de comprendre le processus de fabrication des clefs RSA. Par conséquent, nous avons besoin
d’installer la bibliothèque “GMP” (The GNU Multiple Precision Arithmetic Library). C’est une bibliothèque de calcul
numérique sur des nombres entiers en précision arbitraire. La majorité des fonctions sont optimisées au maximum (en
particulier pour les processeurs Intel : MMX, SSE, etc.).
Les domaines d'utilisation sont la cryptographie, les systèmes de calcul, la sécurité sur Internet, etc.
Installation de GMP :
1) Récupérer le fichier « gmp-5.0.1.tar.bz2 ».
2) Décompresser le fichier à l’aide de la commande « tar xjf … ».
3) Lire le fichier INSTALL et exécuter les commandes suivants en mode super-utilisateur :
./configure
make
make check
Il s’agit simplement de compléter le programme rsa.c (à télécharger sur http://igm.univ-mlv.fr/~rachedi/Teaching.html).
Il faut compléter le programme en particulier à la place du commentaire « /* A COMPLETER */». Une
documentation sur GMP est aussi sur le même lien. Les entiers proposés par la librairie GMP sont des variables
signées de type mpz_t. Chacune de ces variables doit être initialisé à l’aide de la fonction mpz_init avant d’être
utilisée. La librairie GMP propose également une extension de printf notée gmp_printf qui permet l’affichage de
variables de type mpz_t. Toutes les autres fonctions utiles pour ce TP sont décrites dans l’annexe de la page 16.
Le programme rsa.c définit une longueur maximale LONGMESSMAX des messages à chiffrer et utilise le type
uchar en guise de caractère non-signé. Le programme principal manipulera un message m entré au clavier et stocké
dans la chaîne de caractères message. Ce message sera traduit en un entier M dans la variable message_mpz dont la
valeur ne dépassera pas Vmax = 256LONGMESSMAX, c’est-à-dire qu’il sera codé en binaire sur au plus
8×LONGMESSMAX, ce qui n’est pas surprenant puisque chaque caractère du message est codé sur 8 bits.
Outre l’entier message_mpz, le programme principal utilise un système de clefs RSA formé d’une clef publique (n, e)
et d’une clef privée d. Ces trois entiers sont aussi de type mpz_t. Ils seront choisis lors de l’appel de la fonction
fabrique_les_clefs qui prendra en compte la longueur du message, c’est-à-dire la valeur de message_mpz. Plus le
message est long, plus les clefs seront longues...
Une fois les clefs choisies, le programme calculera le chiffré C correspondant à la variable message_ mpz chiffre de
type mpz_t selon la règle de chiffrement RSA : C = Me (mod n).
Le programme calcule et affiche également la valeur déchiffrée D = Cd (mod n), qui est égale à M, ainsi que la chaîne
de caractères correspondante message_dechiffre qui est égale à m.
Rappels de cours La fabrique de clefs RSA se divise en trois parties :
1. Générer deux gros nombres premiers p et q, en les tirants au sort.
Calculer ensuite n = p × q et w = (p − 1) × (q − 1).
2. Trouver deux entiers d et e (inferieurs à n) tels que d × e = 1 (mod w), c’est-à-dire tels que
d × e + k × w = 1 pour un certain k dans Z
Pour cela, il suffit de tirer au sort d et de vérifier qu’un tel e existe, c’est-à-dire que le PGCD de d et de w vaut 1.
L’algorithme d’Euclide permet de déterminer ce PGCD et donc de vérifier qu’un tel e existe. De plus l’algorithme
EIOC-3
TP Sécurité
A. RACHEDI
- 5/6
d’Euclide étendu permet alors de calculer un tel e.
3. Diffuser la clef publique (n, e) mais garder pour soi d : c’est la clef privée ! Il faut aussi oublier w, devenu inutile,
car aucun des calculs de chiffrement ou de déchiffrement n’utilise w. En revanche, la connaissance de w, e et n permet
de calculer (avec l’algorithme d’Euclide étendu) une clef de déchiffrement équivalente à d.
Exercice n°1
Ecrire la fonction « fabrique_les_clefs » selon le procédé suivant :
1. Choisir deux nombres premiers distincts p et q plus grands que M. Vous pourrez utiliser la fonction GMP
mpz_nextprime(x,y) qui place dans x le plus petit nombre supérieur à y et premier.
2. Calculer n = p × q et w = (p − 1) × (q − 1). Vous pourrez utiliser la fonction GMP mpz_sub_ui(x,y,z) qui calcule x
= y − z et la fonction mpz_mul(x,y,z) qui calcule x = y × z.
3. Choisir une valeur pour e petite, afin de faciliter le chiffrement (juste pour cet exercice car cette stratégie affaiblit
RSA...). Pour cela, choisir pour e le plus petit entier ≥ 2 qui est premier avec w, c’est-à-dire que le PGCD de e et w
vaut 1. Vous pourrez utiliser la fonction mpz_gcd qui implémente l’algorithme d’Euclide.
4. Calculer une valeur de d à l’aide de la fonction mpz_gcdext qui implémente l’algorithme d’Euclide étendu.
Vous pourrez tester cette partie du programme en modifiant le main et en fixant une valeur M qui doit aussi être la
valeur déchiffrée. Pour affecter à un entier mpz_t la valeur indiquée par une chaîne de caractère, vous pourrez utiliser
la fonction mpz_set_str.
Par exemple mpz set str(x,"1152921504606846803",10) : Placera la valeur 1152921504606846803, en base 10, dans
l’entier x de type mpz_t.
Exercice n°2 : Encodage et décodage des chaînes de caractères
Le message m est une suite de caractères c0, ..., cl ASCII étendus, sur 8 bits. Ce message est codé par l’entier
Avec ck est un entier compris entre 0 et 255.
Q 1. Ecrire la fonction chaine2mpz qui traduit le message m en un entier M.
Q 2. Ecrire la fonction inverse mpz2chaine qui calcule la chaîne de caractères qui correspond à un entier donné.
Q 3. Tester le programme obtenu.
Exemple d’exécution
$ gcc rsa.c -lgmp -DLONGMESSMAX=10
$ ./a.out
Tapez votre message (Longueur max. = 10): Alfred
Message de 6 caractères -> 3463326578241
Clef_publique_n : 196520034100071057065009920573
Clef_publique_e : 7
Clef_privee_d: 56148581171448620129544540223
Message chiffré : 10132267902671105277276209681
Message déchiffré : 3463326578241
Alfred
EIOC-3
TP Sécurité
A. RACHEDI
- 6/6
Téléchargement