diff --git a/README.md b/README.md index 448a537..1bea230 100644 --- a/README.md +++ b/README.md @@ -16,4 +16,8 @@ Cryptographie - Outils et algorithmes - cm : [Algorithmes à clefs publiques](cours/crypto.pdf). - tp : [Diffie-Hellman](td_tp/tp3) +#### Semaine 4 +- cm : [Signatures, certificats](cours/crypto.pdf). +- tp : [OpenSSL (chiffrements, hashages, signatures, certificats)](td_tp/tp4) + diff --git a/td_tp/tp4/M1.ps.gz b/td_tp/tp4/M1.ps.gz new file mode 100644 index 0000000..b579b86 Binary files /dev/null and b/td_tp/tp4/M1.ps.gz differ diff --git a/td_tp/tp4/M2.ps.gz b/td_tp/tp4/M2.ps.gz new file mode 100644 index 0000000..f00aa6c Binary files /dev/null and b/td_tp/tp4/M2.ps.gz differ diff --git a/td_tp/tp4/README.md b/td_tp/tp4/README.md new file mode 100644 index 0000000..e115be2 --- /dev/null +++ b/td_tp/tp4/README.md @@ -0,0 +1,444 @@ +# TP4 + +> Dans ce tp, on utilise la boîte à outils **openssl** pour : +> +> - Chiffrage/déchiffrage (symétriques et à clés publiques). +> - Hashage. +> - Signature. +> - Création/utilisation de certificats. + +### OpenSSL +<details><summary>Openssl</summary> +<div> +Vous pouvez utiliser les fonctionnalités suivantes : + + ```bash + openssl genrsa -out fichier_rsa.priv size + ``` + +génére la clé privé RSA de taille size. les valeurs possible pour size +sont : 512, 1024, etc. + + ```bash + openssl rsa -in fichier_rsa.priv -des3 -out fichier.pem + ``` + +chiffre la clef privé RSA avec l'algorithme DES3. Vous pouvez utiliser DES, 3DES, IDEA,etc. + + ```bash + openssl rsa -in fichier_rsa.priv -pubout -out fichier_rsa.pub + ``` + +stocke la partie publique dans un fichier à part (création de de la clé +publique associée à la clef privée dans le fichier fichier.pem). + + ```bash + openssl enc -algo -in claire.txt -out chiffre.enc + ``` + +pour le chiffrement de claire.txt avec l'algorithme spécifié (`openssl enc --help` pour avoir la liste des possibilités ou bien openssl +list-cipher-commands) dans un fichier chiffre.enc. + + ```bash + openssl enc -algo -in chiffre -d -out claire + ``` + +pour le déchiffrement. + + ```bash + openssl dgst -algo -out sortie entrée + ``` + +pour hacher un fichier. L'option -algo est le choix de l'algorithme de +hachage (sha, sha1, dss1, md2,md4, md5, ripemd160). + + ```bash + openssl rand -out clé.key nombre_bits + ``` + +pour générer un nombre aléatoire de taille nombre_bits (utiliser +l'option -base 64 pour la lisibilité). + + ```bash + openssl aes-256-cbc -in claire.txt -out chiffre.enc -e -k clé.key + ``` + +pour chiffrer un fichier avec l'AES. + + ```bash + openssl rsautl -encrypt -inkey rsa.pub -in clair.txt -out chiffre.enc + ``` + +chiffrer fichier.txt avec la RSA en utilisant la clef publique rsa.pub. + + ```bash + openssl rsautl -decrypt -inkey rsa.priv -in chiffre.enc -out fihcier.txt + ``` + +pour déchiffrer le fichier fic.dec. + + ```bash + openssl rsautl -sign -inkey ras.priv -in fichier.txt -out fic.sig + ``` + +pour générer une signature. + + ```bash + openssl rsautl -verify -pubin -inkey rsa.pub -in fic.sig + ``` + +pour vérifier une signature. +</div> +</details> + +### Chiffrage symétrique + +#### Avec mot de passe + +La liste des algorithme de chiffrement symétrique est donnée par la +commande + + ```bash + openssl enc -ciphers + ``` + +Pour chiffrer le fichier toto avec le système Blowfish en mode CBC, avec +une clé générée par mot de passe, le chiffré étant stocké dans le +fichier toto.chiffre , on utilise la commande : + + openssl enc -bf-cbc -in toto -out toto.chiffre + +Pour déchiffrer le même message, on utilise la commande : + + openssl enc -bf-cbc -d -in toto.chiffre -out toto.dechiffre + +**Exercice 1** + + - Chiffrer et déchiffrer un fichier de votre choix. Vérifier avec la + commande `diff`. + - Comment expliquer la différence de taille du fichier et du fichier + chiffré ? + - Que se passe-t-il si le mot de passe est invalide ? + +**Exercice 2** + +Le cryptogramme [cryptogramme](./cryptogramme) a été chiffré avec AES en +mode CBC, la clé de 128 bits ayant été obtenue par mot de passe. Sachant +le codage en base 64 du mot de passe est `VHN1bmFtaQo=`, déchiffrez le +cryptogramme. + +#### Avec clé explicite (mode CBC) + +Pour chiffrer le fichier toto avec une clé explicite, il faut utiliser +les options -K (ou -kfile) 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, et une clé de +128 bits : + + openssl enc -bf-cbc -in toto -out toto.chiffre \ + -iv 0123456789ABCDEF \ + -K 0123456789ABCDEF0123456789ABCDEF + +**Exercice 3** + +Générez une clé pour aes-256, ainsi qu'un vecteur d'initialisation +(128 bits). Chiffrez et déchiffrez (AES 256 en mode CBC) le fichier +clair correspondant au cryptogramme de la question précédente. + +### Chiffrage à clé publique + +On peut générer des clés RSA avec la commande + + openssl genrsa -out keyfile size + +**Exercice 4** + +Générez une clé RSA sur 2048 bits dans le fichier key.pem. Que donne +`cat key.pem.` + + openssl rsa -in keyfile -text -noout + +permet de visualiser vos clés + +**Exercice 5** + + - Exportez la partie publique de votre clé dans key.pub.Regardez le + fichier. + - Chiffrez la clé privée avec idea et un mot de passe. Regardez ce que + contient le fichier. + + ```bash + openssl rsa -in maCle.pem -idea -out maCle.pem + ``` + + - Chiffrez "un petit fichier". Quelle est la taille du fichier + chiffré ? Déchiffrez-le. + - Que se passe-t-il pour un gros fichier ? pourquoi ? + +**Exercice 6** + +Envoyez votre clé publique à un camarade. Celui-ci vous enverra la sienne. +Générer un petit fichier texte et envoyez-le à votre voisin chiffré avec +sa clef publique. Lui vous enverra un fichier chiffré avec sa clef. +Renvoyez-lui le message qu'il vous a envoyé mais en clair. + +**Exercice 7** + +Toujours en binome : A génére une clef AES 256 qu'il chiffre avec la +clef publique RSA de B et il lui envoye le chiffré. A partir de là, B +récupère la clef (en clair), et il chiffre un gros fichier avec l'AES et +la clef AES. Il envoie le gros fichier chiffré à A qui doit le +déchiffré. + +### Hachage et mots de passe + +Pour calculer un hachage, utiliez la commande + + openssl dgst -algo -out hash fichier +**Exercice 8** + +1. Visitez les possibilités de la commande prime d’OPENSSL. +2. Testez la primalité d’un nombre donné : en plus de la réponse, constatez que l'écho de ce nombre +a lieu en hexadécimal. +3. Testez la primalité d’un nombre passé directement en hexadécimal. +4. (facultatif) Ecrivez un petit shell-script UNIX de façon à faire afficher les nombres premiers d'un +intervalle donné (utilisez seq ou autre). + +**Exercice 9** + +1. À l'aide de la commande dgst, obtenir dans bash.hash, le hachage du + fichier exécutable `/usr/bin/bash`, en choisissant SHA256 (Secure + Hash Algorithm) comme algorithme de hashage. Refaire pour obtenir la + version binaire du hash dans le fichier executable.hash.bin. + Comparer la taille de `/usr/bin/bash`, de executable.hash et de + executable.hash.bin. Quelle est la longueur du hash en nombre de + bits ? On recommence avec un fichier court oof. Quelle est la + longueur du hash en nombre de bits ? +2. Changer un seul **bit** dans oof. Comment change le hash ? + +3. On recommence avec MD5 (Digest Message) comme algorithme de hashage. + Quelle est la longueur des hashs en nombre de bits. + +4. Récupérez les fichiers [fichier1](./M1.ps.gz) et + [fichier2](./M2.ps.gz). Décompressez-les, et regardez leur contenu. +5. Calculer leur empreinte MD5 avec `openssl`. Conclusion ? + +6. Même question avec SHA-1 et SHA256. +7. S'il s'agit tout simplement de calculer des hashs, on peut utiliser + directement certaines commandes, sans passer par openssl. Par + exemple les commandes md5sum ou shasum. C'est le cas, par exemple, + lorsqu'on télécharge des packages dont on veut vérifier l'intégrité + de la copie (à condition bien sûr que le site officiel de l'éditeur + du package publie le hash du package). + +**Exercice 10** + +Vous vous retrouvez en possession du hachage MD5 d'un mot de passe que +vous voulez casser. + + dde2790ce930e3d425305c36afd4e69c + +Ecrivez un programme force brute qui teste tous les mots d'un +dictionnaire. Pour calculer le hachage MD5 d'une chaîne, utilisez la +fonction MD5 de openssl (-lcrypto à la compilation) + +```c +#include <openssl/md5.h> +unsigned char *MD5(const unsigned char *d, unsigned long n, + unsigned char *md); +``` + +Testez avec le dictionnaire [cracklib-small](./cracklib-small.gz) + +**Exercice 11** + +Vous avez réussi à récupérer le fichier `/etc/shadow` d'un serveur avec +la ligne suivante + + toto:$6$oAwY6QyT$WALN/YdWiU16lh19DqFHgLYYj77Grn3L88L8vX8IkgXQJyxH1r4L9/2zjY1fdM81Sx/cv821MXfPHbP.nvR2W.:16680:0:99999:7::: + +Retrouvez le mot de passe du compte toto en procédant comme à +l'exercice précédent (utliser la fonction `crypt`) + +```c +#include <crypt.h> +char *crypt(const char *key, const char *salt); +``` + +### Signature + +Pour signer un "document", on calcule d'abord une empreinte de ce +document. La commande **dgst** permet de le faire. + + openssl dgst -algo -out hash fichier + +Signer un document revient à signer son empreinte. Pour cela, on utilise +l'option `-sign` de la commande **rsautl**. + + openssl rsautl -sign -in hash -inkey cle -out signature + +et pour vérifier + + openssl rsautl -verify -in signature -pubin -inkey cle -out hash + +**Exercice 12** + +Le fichier [signatures.tar.gz](./signatures.tar.gz) contient deux +fichiers accompagnés d'une signature, ainsi que la clé publique de la +clé RSA ayant produit la signature. De ces deux fichiers, lequels a bien +été signé. + +**Exercice 13** + +Reprenez le binôme de la partie RSA. Envoyez à votre binôme le fichier +/etc/passwd et une signature, qui la vérifiera. + +### Certificats + +#### Création d'une autorité de certification (permettant de signer les demandes de certificats) + +Vous allez jouer le role d'une autorité de certification. + +Par défaut, OpenSSL utilise le fichier de configuration + +``` +/etc/ssl/openssl.cnf +``` + +pour la génération des certificats. Pour utiliser un fichier de +configuration personnalisé, il suffit d'ajouter l'argument "-config +{fichier_de_configuration_personnalisé}" à la commande openssl. +Avant de pouvoir générer un certificat , il faut obligatoirement générer +une clé RSA ou DSA. Générez une clé RSA `mykey.pem` pour l'autorité de +certification chiffrée avec idea. + +Pour générer ses propres certificats, sans passer par une autorité de +certification externe : + + openssl req -new -x509 -key mykey.pem -out ca.crt -days 1095 + +On indique pour le paramètre `-out` le nom de l'autorité de +certification à générer puis la durée de validité en jour avec le +paramètre `-days` Cette autorité de certification permettra de signer +les futures demandes de certificats auto-signés. Cette génération est à +faire une seule fois. Le Common Name à indiquer ne doit correspondre à +aucun nom de domaine ayant besoin d'un certificat. Cette autorité de +certification peut-être mis à disposition du public afin d'être intégré +dans les différents navigateurs comme étant une autorité de +certification reconnue. + +#### Création d'une requête de certificat + +Vous allez jouer le role de quelqu'un qui veut obtenir un certificat +pour sa clé RSA. Générez une clé RSA dans mykey.pem. + +**Exercice 14** + +Générez une requête de demande de certificat pour votre clé. + + openssl req -new -key maCle.pem -out maRequete.pem + +Consulez cette requête avec + + openssl req -in maRequete.pem -text -noout + +**Exercice 15** + +Expliquez les différents éléments contenus dans cette requête. La clé +privée du sujet y figure-t-elle ? + +#### Génération du certificat final + +**Exercice 16** + +A l'aide de la requête de certificat, générez un certificat pour votre +clé publique. Vous jouez donc le role ici de l'authorité de +certification. + + openssl x509 -req -in maRequete.pem -out moncertif.pem -CA ca.crt -CAkey mykey.pem -CAcreateserial -CAserial ca.srl -days 90 + +Affichez ce que contient le certificat. + +L'option `-CAcreateserial` est à utiliser seulement la première fois. +Ceci va générer un identifiant (ca.srl). Lors des prochaines +certification (pour renouvellement ou pour d'autres domaines) +l'identifiant, contenu dans le fichier ca.srl, sera incrémenté à +l'aide de l'option -CAserial ca.srl + +Pour vérifier la validité d'un certificat, on peut utiliser la commande +verify : + + openssl verify -CAfile ca.crt moncertif.pem + +**Exercice 17** + +Vérifier le certificat généré. + +#### ncat avec SSL/TLS + +On va utiliser ncat qui supporte SSL/TLS. + +1. Avec tcp, échangez un fichier entre un client et un serveur ncat. + Vérifier avec tcpdump que le fichier passe **en clair** !. +2. Refaire la question précédente en utilisant SSL/TLS. + - Le serveur a maintenant besoin du certificat, et de la clé privé + correspondante (option `--ssl-cert` et `--ssl-key`) + - Le client doit aussi se connecter avec l'option `--ssl`. + - Le contenu du "fichier" échangé passe-t-il encore "en clair" + ? + +3. Que se passe-t-il coté client si vous rajoutez l'option + `--ssl-verify` ? + + ncat --ssl-verify --ssl localhost port + +4. Avec l'option `--ssl-trustfile`, dites à ncat de faire confiance à + l'autorité de certification qui a signé le certificat du serveur. +5. Connectez-vous au serveur ncat en utilisant votre browser. Pour + cela, faites un fichier `rep.http` qui contient une réponse http qui + sera renvoyée au navigateur. Par exemple + + ```html + HTTP/1.1 200 OK + + <html> + <head> + <title>TP</title> + </head> + <body> + <h1>TEST</h1> + </body> + </html> + ``` + + Le serveur renvoie systématiquement la même réponse : + + ncat -l 8080 < rep.http + + Vérifiez depuis votre navigateur. + +6. On veut cette fois-ci se connecter à notre serveur ncat en https. On + utilise localhost comme nom. +7. Testez depuis votre navigateur. Que se passe-t-il ? Dites au + navigateur que vous faites confiance à l'autorité qui a signé le + certificat du serveur (comment ?) +8. Malgré tout, cela ne suffit pas. Le navigateur devrait vous réclamer + l'extension `subject Alternative Names` qui permet d'associer + emails, ip, noms, etc. En l'occurence, il faut associer le nom + localhost au certificat. + + En tant qu'autorité de certification, recréez le certificat du + serveur en ajoutant localhost comme nom associé au certificat. + + openssl x509 -req -in maRequete.pem -out moncertif.pem -CA ca.crt -CAkey mykey.pem -CAcreateserial -CAserial ca.srl -days 90 -extfile x509.cnf + + le fichier x509.cnf + + subjectAltName = DNS:localhost + + Retestez. diff --git a/td_tp/tp4/cracklib-small.gz b/td_tp/tp4/cracklib-small.gz new file mode 100644 index 0000000..298a4c4 Binary files /dev/null and b/td_tp/tp4/cracklib-small.gz differ diff --git a/td_tp/tp4/cryptogramme b/td_tp/tp4/cryptogramme new file mode 100644 index 0000000..d495db2 Binary files /dev/null and b/td_tp/tp4/cryptogramme differ diff --git a/td_tp/tp4/signatures.tar.gz b/td_tp/tp4/signatures.tar.gz new file mode 100644 index 0000000..5ace18a Binary files /dev/null and b/td_tp/tp4/signatures.tar.gz differ