Ressources

News

La cryptographie pour le stockage et l’échange de données sécurisées – Partie 3

3. Le hachage

Après avoir expliqué le fonctionnement, les avantages et les inconvénients des modes de chiffrement symétriques et asymétriques, nous nous intéressons dans cette dernière partie au mécanisme de « hachage ».

Ce procédé répond notamment aux problématiques suivantes :

  • Comment stocker de manière sécurisée un mot de passe, sans qu’un administrateur ne puisse en prendre connaissance.
  • Comment contrôler l’intégrité d’un message envoyé.

3.1 Principe

Contrairement au chiffrement, le hachage est un procédé cryptographique non-réversible. C’est-à-dire qu’en possédant le résultat de ce procédé, que l’on appelle un hash, un condensat ou encore une empreinte, on ne peut pas retrouver mathématiquement le texte initial. Une autre propriété du hachage est que pour chaque texte soumis à ce procédé, le résultat doit être unique. Mais que deux textes identiques doivent produire un résultat identique. Enfin, les empreintes produites doivent être de la même taille, quel que soit le texte saisi.

Prenons un exemple trivial pour illustrer. Le procédé consistant à supprimer une lettre sur deux d’un texte répond bien au principe de non-réversibilité, mais pas d’unicité. Il est aisé de trouver deux textes qui produiront la même empreinte :

Figure 16 : Exemple trivial d'un mauvais procédé de hachage
Figure 16 : Exemple trivial d’un mauvais procédé de hachage

À partir de l’empreinte « mtd as », et même en connaissant le procédé utilisé, il n’est pas possible de retrouver le texte « mot de passe », puisqu’une partie de l’information est « perdue » dans le procédé, contrairement au chiffrement. Mais en appliquant le même procédé au texte « mat de masse », on obtient la même empreinte, notre procédé est donc faillible. 

Ces empreintes sont utilisées pour de nombreuses problématiques, par exemple :

  • Pour stocker des mots de passe dans une base de données,
  • Pour réaliser des signatures numériques,
  • Pour effectuer des contrôles d’intégrité,
  • Pour de l’identification de données,
  • Pour effectuer une preuve de travail, …

Intéressons-nous au premier cas, avec notre exemple de hachage trivial.

Lorsqu’un utilisateur souhaite se connecter à un site web, il est généralement attendu qu’il saisisse un identifiant et un mot de passe. Si les informations saisies sont exactes, alors l’utilisateur accède à son compte. Le mot de passe doit donc être vérifié par le site web. Mais, puisqu’il s’agit d’une information secrète, il n’est pas souhaitable que ce site web « connaisse » la valeur du mot de passe de l’utilisateur. Il n’en conserve donc qu’une empreinte.

Ainsi, lorsque l’utilisateur va saisir son mot de passe « mot de passe », le site va effectuer le procédé de hachage sur ce texte, obtenir l’empreinte « mtd as », et la comparer avec la valeur stockée dans sa base de données, avant d’autoriser ou non l’utilisateur à entrer. Il ne conserve pas la valeur « mot de passe » en l’état.

Ainsi, même si un attaquant parvient à récupérer le contenu de la base de données, il ne pourra pas retrouver ce mot de passe. Sans cette protection, l’attaquant aurait pu tenter d’usurper l’identité de l’utilisateur et se connecter avec les identifiants volés sur ce site web (et sur tous les autres sites sur lesquels l’utilisateur a utilisé la même paire d’identifiant/mot de passe).

En pratique, des algorithmes de hachage tels que MD5 ou SHA1 vont utiliser un découpage du message initial par N blocs de taille fixe (en complétant le dernier bloc (n°N) avec du padding, une suite de 0,si nécessaire), effectuer une opération mathématique de hachage sur chaque bloc, et réutiliser le résultat de cette opération pour le bloc suivant.

Figure 17 : Processus de hachage simplifié
Figure 17 : Processus de hachage simplifié

Ainsi, chaque « partie » du message va avoir une incidence sur le résultat final, contrairement à l’exemple que nous avons vu précédemment, et deux messages très proches donneront une empreinte finale différente.

Voici ci-dessous quelques exemples réels d’empreintes SHA1 pour différents messages : 

Figure 18 : Exemples d'empreintes SHA1 de plusieurs messages
Figure 18 : Exemples d’empreintes SHA1 de plusieurs messages

Synthétisons : une empreinte permet, pour un message donné, d’obtenir un message beaucoup plus court, fidèle au message initial.

Dans la partie précédente nous avions simplifié la description des certificats en considérant qu’une signature correspondait au message initial, donc le certificat complet, chiffré avec la clé privée d’une autorité de certification. En pratique, ce n’est pas le certificat complet mais une empreinte qui est utilisée pour la signature. Ainsi, même si le certificat (ou tout autre type de message que l’on veut signer) est extrêmement long, son empreinte, et donc sa signature, seront toujours de taille fixe (variable selon les algorithmes utilisés).

3.2 Contrôle d’intégrité

Nous avons vu l’utilisation des empreintes dans le cadre des signatures numériques. Elles peuvent également être utilisées pour contrôler l’intégrité de données.

Prenons à nouveau un exemple trivial que l’on peut rencontrer sur Internet. Lorsqu’Alice télécharge un fichier volumineux, elle peut s’interroger sur la fiabilité de l’envoi, ou si le fichier qu’elle a réceptionné après son téléchargement est bien exactement conforme à ce qu’elle attend. Pour cela, il peut arriver que des sites web indiquent une empreinte de contrôle dans les pages de téléchargement, permettant aux utilisateurs de vérifier que le fichier reçu est bien conforme.

C’est le cas par exemple pour télécharger l’image d’installation de la distribution Kali Linux utilisée en sécurité offensive :

Figure 19 : Exemple de contrôle d'intégrité
Figure 19 : Exemple de contrôle d’intégrité

Source : https://www.kali.org/get-kali/#kali-installer-images 

Bien que le fichier image pèse 3,9Go, l’empreinte SHA256 ne fait que 64 caractères.

Une fois son téléchargement terminé, Alice pourra utiliser une commande semblable à celles présentées en Figure 18 pour générer l’empreinte de son fichier et la comparer avec celle du site.

Ce procédé est très couramment utilisé de manière automatisée et transparente dans les protocoles de communication sous la forme de checksum, par exemple dans le protocole TCP.

3.3 Sel et mots de passe

Les empreintes sont donc très utiles pour vérifier l’intégrité des messages (contrôle d’intégrité) et pour en garantir l’origine (signature).

Comme présenté rapidement en début de cet article, elles servent aussi à conserver des mots de passe dans des bases de données.

Plaçons-nous alors cette fois dans la position de Charlie, l’attaquant, qui est parvenu à obtenir une base de données d’un site web :

Figure 20 : Exemple de base de données contenant des empreintes de mots de passe
Figure 20 : Exemple de base de données contenant des empreintes de mots de passe

Charlie ne peut pas se connecter directement avec ces éléments, puisqu’il s’agit d’empreintes.

Nous avons vu que le procédé de hachage était irréversible, cela signifie qu’il n’existe aucune opération mathématique permettant de retrouver le message initial à partir de l’empreinte. Néanmoins, il existe des techniques pour tenter de retrouver un mot de passe, si celui-ci n’est pas suffisamment robuste.

En effet, en possession de ces trois empreintes, Charlie pourrait tenter d’imaginer des mots de passe choisis par les trois utilisateurs, établir une liste de ces mots de passe probables, et leur appliquer la même fonction de hachage. Cette opération a l’avantage de pouvoir être menée « hors-ligne », et de dépendre uniquement de la puissance de calcul disponible de Charlie.

En pratique, les attaquants et les pentesteurs ont recours à des dictionnaires de mots de passe usuels, construits à partir de base de données fuitées ou de mots prédictibles (comme le nom de l’entreprise, des prénoms et des dates). Une base largement utilisée est « rockyou », que l’on peut retrouver par exemple dans l’archive SecLists.

Tout le monde peut accéder à cette base pour vérifier par exemple que son mot de passe, ou un dérivé, ne s’y trouve pas.

Le fichier rockyou.txt comprend 14 millions de mots de passe usuels.

L’attaque par « dictionnaire » va alors consister à identifier l’algorithme utilisé par la base de données, à hacher ces 14 millions de mots de passe avec le même algorithme, et à comparer l’ensemble de ces empreintes aux empreintes de la base de données. Si l’on dispose déjà de cette base d’empreintes, il s’agira d’une attaque dite de « rainbow table ».

Cette attaque peut être réalisée de manière automatique avec l’outil « hashcat ».

Dans la capture ci-dessous, nous réalisons cette attaque, contre les trois empreintes observées dans la figure précédente et avec le dictionnaire « rockyou ».

Note :

Seules certaines données sont conservées dans les captures ci-dessous pour en assurer la lisibilité.

Figure 21 : Réalisation de l'attaque par dictionnaire
Figure 21 : Réalisation de l’attaque par dictionnaire

Avec notre machine de faible puissance, l’outil hashcat a eu besoin de 3 secondes pour effectuer le calcul sur 11 millions d’empreintes, à raison de 4,8 millions de hash/seconde, et pour les comparer aux trois empreintes de la base de données (les 3 mots de passe ayant été découverts, l’outil n’a pas eu besoin de calculer les 14 millions).

Charlie a désormais accès aux trois mots de passe : Soleil101, Password123* et Damian24. 

Note :

Ces mots de passe sont « faibles » dans la mesure où ils suivent un format assez standard :ils commencent par une majuscule, utilise des mots du dictionnaire ou des prénomsen minuscule et finissent par des chiffres et des caractères spéciaux, mais ils sont pourtant acceptés par de nombreuses politiques de mots de passe.

Plutôt que d’utiliser une attaque par dictionnaire, il est possible de tester toutes les possibilités de mots de passe. Par exemple, pour un mot de passe de 8 caractères : de « aaaaaaaa » à « !!!!!!! » en passant par « Damian24 ». Il s’agit alors d’une attaque par force-brute qui aura l’intérêt d’être exhaustive, mais l’inconvénient d’être extrêmement gourmande en ressources.

Sur notre machine faible, une telle attaque, avec l’ensemble de toutes les combinaisons possibles de minuscules, majuscules, chiffres et caractères spéciaux sur 8 caractères, prendrait plusieurs années :

Figure 22 : Réalisation de l'attaque par force-brute sur 8 caractères
Figure 22 : Réalisation de l’attaque par force-brute sur 8 caractères

C’est généralement ce type d’attaque dont on parle lorsque l’on présente des « tableaux de temps nécessaire pour trouver un mot de passe », tel que celui-ci :

Figure 23 - Tableau de robustesse des mots de passe
Figure 23 – Tableau de robustesse des mots de passe

Source : https://www.francenum.gouv.fr/magazine-du-numerique/combien-de-temps-un-pirate-met-il-pour-trouver-votre-mot-de-passe-comment 

Note :

Rappelons qu’il nous a suffi de 3 secondes pour casser le mot de passe « Password123* » qui contient pourtant 12 caractères, et l’ensemble des 4 classes de caractères. Ces tableaux sont donc à prendre avec des pincettes, puisque les attaquants préféreront des attaques par dictionnaires que des attaques par force-brute, et même dans ce deuxième cas, préféreront utiliser des masques pour accélérer leurs attaques.

Revenons à nos moutons, et à notre exemple de base de données fuitée et d’attaque par dictionnaire. Si cette base contenait des centaines d’utilisateurs, il faudrait exactement les mêmes quelques secondes à l’attaquant pour tester l’ensemble des 14 millions de possibilités de rockyou. 

De plus, si plusieurs utilisateurs ont le même mot de passe, alors cette information sera tout de suite visible dans la base de données, puisque les empreintes seront identiques pour ces utilisateurs, et l’attaquant n’aura pas besoin d’effectuer un nouveau calcul.

Pour parer à ces points, la notion de « sel » a été introduite.

Un « sel », en cryptographie, correspond à une information non secrète qui est ajoutée avant l’opération de hachage afin de diminuer l’efficacité des attaques de cassage hors-ligne, et d’empêcher que deux empreintes puissent être identiques dans la base.

Ainsi, plutôt que de hacher directement « Soleil101 », le site web va ajouter une valeur aléatoire qui sera concaténée au mot de passe et hachée : « Soleil1011234567 ». Cette valeur a nettement moins de chance d’exister dans un dictionnaire ; et en augmentant la longueur de la chaîne, le sel complique considérablement une attaque par force-brute sur cet élément (cette fois, on peut considérer le tableau de la Figure 23).

Dans notre base de données, l’ajout d’un sel va se présenter de la façon suivante :

Figure 24 : Base de données contenant des empreintes et des sels
Figure 24 : Base de données contenant des empreintes et des sels

On notera que l’empreinte stockée dans le champ « Password » n’est plus la même, puisque cette fois le hachage s’est fait sur la valeur « motdepasse+sel ».

Afin de mener l’attaque par dictionnaire, il va alors être nécessaire de concaténer le sel du premier utilisateur « 1234567 » sur l’ensemble de nos 14 millions de possibilités, avant de les hacher et de comparer à l’empreinte d’Alice. Puis de concaténer la valeur « 5976248 » à nouveau, de recalculer les 14 millions d’empreintes, etc.

Figure 25 : Hachage de rockyou.txt pour chaque sel de la base de données
Figure 25 : Hachage de rockyou.txt pour chaque sel de la base de données

Pour 100 utilisateurs dans la base de données, il serait donc nécessaire de calculer les 14 millions « d’empreintes salées » de rockyou 100 fois.

En réalisant une nouvelle fois une attaque par dictionnaire contre ces « empreintes salées », on voit que notre outil a dû cette fois tester 33 millions de possibilités avant de parvenir à retrouver les trois mots de passe :

Figure 26 : Cassage des mots de passe salés
Figure 26 : Cassage des mots de passe salés

Le sel permet donc de se prémunir contre les attaques de type « rainbow table » (où les empreintes à tester sont déjà pré-calculées), les attaques par force-brute (puisque la longueur de la valeur à découvrir augmente fortement) et de ralentir les attaques par dictionnaire, puisque l’ensemble du dictionnaire devra être à nouveau calculé pour chaque empreinte présente dans la base.

Il existe également des algorithmes spécifiques, tels que bcrypt, spécialement conçus pour rendre difficile ce type d’attaque grâce à leur temps de calcul beaucoup plus long. Ce temps de calcul est totalement transparent pour l’utilisateur puisque le site web va effectuer une seule fois l’opération pour vérifier que le mot de passe est le bon, mais va être drastiquement plus longue pour l’attaquant obligé de répéter le calcul 14 millions de fois.

A titre d’exemple, l’opération de calcul de bcrypt sur le dictionnaire rockyou sur notre machine très peu puissante nécessite environ 4 jours, à comparer aux 3 secondes pour MD5.

Figure 27 : Temps de calcul pour bcrypt
Figure 27 : Temps de calcul pour bcrypt

Avec un sel sur chaque empreinte, il nous faudrait donc 3*4 jours pour comparer ce dictionnaire aux empreintes de la base de données.

3.4 Conclusion

Les procédés de chiffrement symétrique et asymétrique présentés dans les deux premières parties de cette série ont permis de comprendre comment la confidentialité des données échangées sur Internet était assurée. Particulièrement, la notion de signature du chiffrement asymétrique a également rendu possible le contrôle de l’authenticité d’un message.

Le mécanisme de hachage permet de rajouter un contrôle d’intégrité efficace indispensable à la sécurité des communications. Enfin, la digression sur le stockage des mots de passe a mis en lumière les différentes manières de s’attaquer à des empreintes de mots de passe.

Article rédigé par : Florence H. , consultante chez Coralium

Si vous voulez en savoir davantage sur nos offres, en lien avec le sujet de l’article, nous vous proposons de découvrir : Politique de Sécurité des Systèmes d’Information (PSSI)

Références :

L’ensemble des icônes utilisés dans les schémas proviennent de Freepik sur Flaticon 

Exemple de contrôle d’intégrité présent sur un site de téléchargement 

Listes de bases de mots de passe usuels 

Tableau de robustesse de mots de passe

Bcrypt