USTL - Licence et Master Informatique 2006-2007 Principes et Algorithmes de Cryptographie TP 2 : Chiffrement par blocs Objectifs du TP utiliser openssl pour chiffrer/déchiffrer, étudier le remplissage (padding) du dernier bloc, effectuer une attaque utilisant une fuite d information. Outils utilisés openssl, boîte à outils cryptographiques, un oracle. 1 Présentation de openssl 1.1 Protocole SSL Le protocole SSL (Secure Socket Layer) a été développé par la société Netscape Communications Corporation pour permettre aux applications client/serveur de communiquer de façon sécurisée. TLS (Transport Layer Security) est une évolution de SSL réalisée par l IETF. La version 3 de SSL est utilisée par les navigateurs tels Netscape et Microsoft Internet Explorer depuis leur version 4. SSL est un protocole qui s intercale entre TCP/IP et les applications qui s appuient sur TCP. Une session SSL se déroule en deux temps : 1. une phase de poignée de mains (handshake) durant laquelle le client et le serveur s identifient, conviennent du système de chiffrement et d une clé qu ils utiliseront par la suite ; 2. une phase de communication proprement dite durant laquelle les données échangées sont compressées, chiffrées et signées. L identification durant la poignée de mains est assurée à l aide de certificats X509. 1.2 openssl openssl est une boîte à outils cryptographiques implémentant les protocoles SSL et TLS qui offre : 1. une bibliothèque de programmation en C permettant de réaliser des applications client/serveur sécurisées s appuyant sur SSL/TLS. 2. une commande en ligne (openssl) permettant la création de clés 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 ; 1
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 $ o p e n s s l <commande> <options > (le $ étant le prompt du shell) Dans le texte qui suit, les commandes invoquant openssl supposent que cette commande est dans votre variable shell PATH. 2 Chiffrement symétrique avec openssl C est la commande enc qui permet de chiffrer/déchiffrer avec openssl : $ o p e n s s l enc <options > Parmi les options, on doit indiquer le système de chiffrement à choisir dans la liste aes-128-cbc aes-128-ecb aes-192-cbc aes-192-ecb aes-256-cbc aes-256-ecb AES 128 bis in CBC mode AES 128 bis in ECB mode AES 192 bis in CBC mode AES 192 bis in ECB mode AES 256 bis in CBC mode AES 256 bis in ECB mode base64 Base 64 bf-cbc bf bf-cfb bf-ecb bf-ofb cast-cbc cast cast5-cbc cast5-cfb cast5-ecb cast5-ofb des-cbc des des-cfb des-ofb des-ecb des-ede-cbc Blowfish in CBC mode Alias for bf-cbc Blowfish in CFB mode Blowfish in ECB mode Blowfish in OFB mode CAST in CBC mode Alias for cast-cbc CAST5 in CBC mode CAST5 in CFB mode CAST5 in ECB mode CAST5 in OFB mode DES in CBC mode Alias for des-cbc DES in CBC mode DES in OFB mode DES in ECB mode Two key triple DES EDE in CBC mode 2
des-ede des-ede-cfb des-ede-ofb des-ede3-cbc des-ede3 des3 des-ede3-cfb des-ede3-ofb desx idea-cbc idea idea-cfb idea-ecb idea-ofb rc2-cbc rc2 rc2-cfb rc2-ecb rc2-ofb rc2-64-cbc rc2-40-cbc rc4 rc4-64 rc4-40 rc5-cbc rc5 rc5-cfb rc5-ecb rc5-ofb Alias for des-ede Two key triple DES EDE in CFB mode Two key triple DES EDE in OFB mode Three key triple DES EDE in CBC mode Alias for des-ede3-cbc Alias for des-ede3-cbc Three key triple DES EDE CFB mode Three key triple DES EDE in OFB mode DESX algorithm. IDEA algorithm in CBC mode same as idea-cbc IDEA in CFB mode IDEA in ECB mode IDEA in OFB mode 128 bit RC2 in CBC mode Alias for rc2-cbc 128 bit RC2 in CBC mode 128 bit RC2 in CBC mode 128 bit RC2 in CBC mode 64 bit RC2 in CBC mode 40 bit RC2 in CBC mode 128 bit RC4 64 bit RC4 40 bit RC4 RC5 cipher in CBC mode Alias for rc5-cbc RC5 cipher in CBC mode RC5 cipher in CBC mode RC5 cipher in CBC mode Remarque : base64 n est pas un système de chiffrement, mais un codage des fichiers binaires avec 64 caractères ASCII. Ce codage est utilisé en particulier pour la transmission de fichiers binaires par courrier électronique. 2.1 Chiffrement avec mot de passe 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 : $ o p e n s s l enc bf cbc in t oto out toto. c h i f f r e 3
Pour déchiffrer le même message, on utilise la commande : $ o p e n s s l enc bf cbc d in toto. c h i f f r e out toto. d e c h i f f r e Vérification $ d i f f toto toto. d e c h i f f r e Exercice 1 : Q 1. Chiffrez le fichier de votre choix avec le système 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. Tentez de déchiffrer un cryptogramme en utilisant un mauvais mot de passe. Comment réagit openssl? Exercice 2 : Le fichier cryptogram6 a été chiffré avec le système AES en mode CBC, la clé de 128 bits ayant été obtenue par mot de passe. Q 1. Le mot de passe codé en base 64 est Y29tdGVzc2UK. À l aide de la commande openssl appropriée, décodez le mot de passe. Q 2. Déchiffrez ensuite le cryptogram6. 2.2 Chiffrement avec clé 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 1. 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. $ o p e n s s l enc bf cbc in t oto out toto. c h i f f r e \ i v 0123456789ABCDEF \ K 0123456789ABCDEF0123456789ABCDEF Exercice 3 : Q 1. Chiffrez le fichier clair7 avec le système Blowfish en mode OFB, en utilisant le vecteur d initialisation (option -iv) et la clé (option -K) de votre choix pour obtenir le fichier cryptogram7. Déchiffrez ensuite le cryptogramme obtenu. Q 2. Chiffrez le fichier clair correspondant au cryptogram6 avec le même système, la même clé et le même vecteur d initialisation que dans la question qui précède. Q 3. Utilisez le programme xor pour faire un xor des deux fichiers clairs. Utilisez le même programme pour faire un xor des deux chiffrés. Faîtes un diff entre les deux fichiers obtenus. 1 Curieusement, openssl exige un vecteur d initialisation même pour le mode ECB. 4
Que constatez-vous?. Le résultat aurait-il été le même si on avait utilisé un système de chiffrement autre que Blowfish? Explication. Usage : xor <fichier1> <fichier2> <fichier3> <fichier1> et <fichier2>: fichiers à xorer <fichier1> doit ^etre de taille <= à <fichier2> <fichier3> : fichier résultat 3 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. Par exemple, s il manque trois octets au message m = o 1 o 2 o 3 o 4 o 5 pour obtenir un bloc de huit octets, on ajoute trois octets égaux à 3 o 1 o 2 o 3 o 4 o 5 03 03 03 Tab. 1 Complétion d un bloc avec trois octets 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. Par exemple, pour des blocs de huit octets, on ajoute le bloc 08 08 08 08 08 08 08 08 Tab. 2 Complétion par un bloc entier de huit octets Exercice 4 : En chiffrant des fichiers de taille différentes, avec le système Blowfish (blocs de 64 bits) avec une clé 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 5 : En chiffrant des fichiers de taille différentes, avec le système Blowfish (blocs de 64 bits) avec une clé 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 correpsondent 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 : 5
1. la clé utilisée lors du déchiffrement est incorrecte, 2. le vecteur d initialisation est incorrect, 3. le dernier bloc chiffré est erroné, 4. en mode CBC, l avant dernier bloc est erroné. Exercice 6 : Chiffrez avec le système Blowfish en mode CBC et en précisant clé 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. 4 Une attaque utilisant une fuite d information En 2002, Serge Vaudenay, de l école polytechnique fédérale de Lausanne, a montré comment un attaquant ayant intercepté une suite de blocs chiffrés en mode CBC avec un système de chiffrement par blocs quelconque, peut retrouver les blocs clairs correspondant sans avoir à chercher la clé, s il a la possibilité de soumettre au déchiffrement les blocs de son choix. Cette attaque est décrite dans [Vau02] et dans [Jun02]. 4.1 Description de l attaque L attaquant a réussi à intercepter une suite C 1, C 2,..., C n de blocs chiffrés consécutifs, ainsi que le vecteur d initialisation IV, obtenus par un chiffrement par blocs utilsé en mode CBC. Le but de l attaque est de déterminer les blocs clairs M 1, M 2,... M n correspondant. Peu importe le système de chiffrement utilsé, seule compte la taille des blocs du système. L attaque entre dans la catégorie des attaques à chiffrés choisis. L attaquant va décrypter séparément chaque bloc C i en construisant de faux messages chiffrés formés de deux blocs A et C i, A étant un bloc qu il choisit à sa convenance. L attaquant transmet ce cryptogramme forgé à un oracle qui connaît la clé et qui en retour lui dira si oui ou non il a réussi à déchiffrer le cryptogramme. L attaquant peut envoyer autant de cryptogrammes forgés qu il le souhaite en adaptant le choix du bloc A. Les bits d information que l oracle transmet à l attaquant vont se révéler très utiles, puisqu ils lui permettront de retrouver petit à petit le bloc clair. Voici comment. Avec un bloc A choisi de manière complètement arbitraire, la probabilité que l oracle parvienne à déchiffrer correctement le message (A, C i ) est donnée par la formule Pr(succes) = T p i (1) i=1 = p 1 pt 1 p (2) = p q (1 pt ) (3) p q (4) 6
où p = 1 256, q = 1 p = 255 256 et T est la taille en octets d un bloc (T = 8 pour le DES et pour 1 Blowfish, T = 16 pour l AES). Cette probabilité vaut donc approximativement 255. Un succès signifie un bourrage correct, autrement dit le bloc M = A D k (C i ) (5) où D k désigne la fonction de déchiffrement avec la clé k, se termine par un octet égal à 01, ou deux octets égaux à 02, etc... Bien entendu, l attaquant ne sait pas quelle est la situation effective, mais il peut estimer la probabilité de chacun des cas. La probabilité que le bourrage soit constitué de X = j octets égaux à j est donnée par Pr(X = j succes) = p j Pr(succes) (6) = qpj 1 1 p T (7) 255 256 j (8) Cela montre qu en cas de succès il y a approximativement 255 chances sur 256 que M se termine par l octet 01. L attaquant peut d ailleurs facilement vérifier que c est bien l octet 01 en interrogeant l oracle avec une modification du bit de poids faible de l avant dernier octet du bloc A. S il obtient un nouveau succès c est que le dernier octet de M est 01. Une façon d obtenir un bloc A tel que le déchiffrement de (A, C i ) soir un succès consiste à fixer arbitrairement les T 1 premiers octets de A et à faire varier systématiquement le dernier jusqu à obtenir un déchiffrement réussi. De l équation 5 et de la forte probabilité que le dernier octet de M soit 01, l attaquant en déduit la relation suivante liant l octet le plus à droite des blocs A et D k (C i ) 01 = a T d T (9) a 1 a 2 a 3 a 4 a 5 a 6 a 7 a 8 Tab. 3 Les T = 8 octets du bloc A m 1 m 2 m 3 m 4 m 5 m 6 m 7 01 Tab. 4 Les T = 8 octets du bloc M correctement bourré d 1 d 2 d 3 d 4 d 5 d 6 d 7 d 8 Tab. 5 Les T = 8 octets du bloc D k (C i ) 7
et donc la connaissance de d T d T = a T 01 (10) Et comme il connaît aussi le bloc chiffré précédent C i 1 qui vérifie la relation de chaînage C i 1 M i = D k (C i ) (11) avec le bloc clair (inconnu) M i, il peut en déduire l octet le plus à droite du bloc clair m i T = c i 1 T a T 01 (12) Ainsi l attaquant connaît l octet le plus à gauche du bloc clair M i. Il peut passer maintenant à la recherche de l octet clair qui précède. Pour cela, il fixe arbitairement les T 2 premiers octets du bloc A, il fixe le dernier octet de A de sorte que 02 = a T d T (13) et il fait varier l avant dernier jusqu à obtenir une réponse positive de l oracle. Et il procède ainsi jusqu à découvrir le bloc clair M i en entier. Estimation du coût de cette attaque : Pour chacun des T octets d un bloc il faut interroger l oracle entre 1 et 256 fois. En moyenne 128 questions suffisent. Pour obtenir un bloc clair complet, il faut donc entre T et 256T questions, 128T questions en moyenne. Avec T = 8, un bloc est décrypté en au plus 2048 questions, et en moyenne 1024 questions. 4.2 Mise en œuvre de l attaque Vous allez mettre en œuvre cette attaque sur le cryptogramme cryptogram8. Ce cryptogramme a été obtenu en chiffrant un fichier contenant un mot de passe avec un système de chiffrement par blocs de 64 bits en mode CBC. Le vecteur d initialisation utilisé est IV =0102040810204080. Le cryptogramme ayant une taille de 16 octets, il est donc constitué de deux blocs C 1 et C 2. Avec le vecteur d initialisation vous avez trois blocs consécutifs. Votre but est de décrypter les deux blocs C 1 et C 2 sans connaître ni le système de chiffrement ni la clé utilisés. Pour cela, vous utiliserez l oracle implanté par les fichiers oracle.h et oracle.c et par un serveur 2. Cet oracle est défini par trois fonctions et une macro : 1. #define ORACLE hote hébergeant le serveur donne l adresse du serveur auquel l oracle doit s adresser ; 2. int ouvre oracle(char hote) établit la connexion de l oracle avec le serveur ; 3. int ferme oracle(void) ferme cette connexion, 4. int interroge oracle (char msg) interroge l oracle en lui posant la question passée en paramètre : la réponse 0 signifie un échec dans le déchiffrement (pour cause de bourrage incorrect), la réponse 1 signifie succès du déchiffrement. 2 dont vous n aurez pas le code, puisqu il contient la clé de chiffrement utilisée 8
Le programme attaque.c interroge l oracle avec des questions construites en concaténant deux blocs : le premier bloc est choisi, le second bloc est le premier bloc du cryptogramme que l on tente de décrypter. Le programme s arrête dès que l oracle répond par un succès (valeur 1), ce qui correspond au cas où le bourrage du dernier bloc déchiffré est correct. Q 1. Récupérez les fichiers attaque.c, oracle.h, oracle.c, tools.h et tools.c, compilez-les et exécutez le programme attaque. Déduisez-en la valeur du dernier octet du bloc à décrypter. Q 2. En modifiant le programme attaque.c, poursuivez le décryptement du premier bloc de cryptogram8. Q 3. Décryptez ensuite le second bloc de cryptogram8. Q 4. Retrouvez le mot de passe et déchiffrez le cryptogram9 qui a été chiffré avec le système Blowfish en mode CBC. Vous obtiendrez un fichier au format Ogg Vorbis que vous pourrez écouter avec la commande ogg123. Q 5. Écoutez la chanson obtenue avec la commande $ ogg123 toto Références [Jun02] Pascal Junod. Problèmes d implémentation de la cryptographie. les attaques par effet de bord. MISC, (4) :78 81, novembre-décembre 2002. [Vau02] Serge Vaudenay. Security flaws induced by cbc padding. applications to ssl, ipsec, wtls,.... In Advances in Cryptology, EUROCRYPT 02, LNCS 2332, pages 534 545. Springer-Verlag, 2002. 9