Présentation des fonctions de hachage SHA-2

Je continue sur ma lancée, à la découverte du livre de David Wong, Real-World Cryptography, paru aux éditions Manning. Dans ce deuxième article, je vais aborder le fonctionnement théorique des fonctions de hachage. Je ne parlerai pas des raisons qui ont conduit MD5 et SHA-1 à être considérés comme non sécurisées. La découverte de SHA-3, que je prévoyais d’intégrer directement après SHA-2, sera finalement abordé dans article dédié.

Secure Hash Algorithm 2 est une famille de fonctions de hachage composée de 6 membres. La différence la plus visible entre eux est la taille du condensat en sortie. Cette famille est basée sur la construction de Merkle-Damgård.

Son objectif est simple : à partir d’une donnée de taille quelconque, produire une sortie de taille fixe tout en répondant aux Propriétés fondamentales de sécurité des fonctions de hachage. Pour les plus curieux, j’avais déjà présenté Ralph Merkel et ses puzzles dans mon article La cryptographie asymétrique avec Diffie-Hellman. La famille est composée des fonctions suivantes :

  • SHA-224,
  • SHA-256,
  • SHA-384,
  • SHA-512,
  • SHA-512/224,
  • SHA-512/256.

Ces deux derniers membres voient leurs condensats tronqués à 224 bits et 256 bits respectivement. SHA-256 et SHA-512 sont les deux fonctions les plus utilisées. SHA-2, pour fournir son condensat, exploite la compression des données. Cela n’a rien à voir avec les algorithmes de compression bidirectionnels dont l’objectif est la diminution de l’espace occupé sur le support numérique.

Dans la famille SHA-2, la compression est basée sur la construction de Davies-Meyer. Pour être précis, la construction de Merkle-Damgård inclus une fonction de compression unidirectionnelle qui, dans le cas de SHA-2 est celle de Davis-Meyer mais il en existe d’autres.

Cette fonction de compression est basée sur un algorithme de chiffrement symétrique par blocs « sans clé ». Il faut comprendre sans clé dans le sens où l’utilisateur ne fournit pas directement une clé de chiffrement, c’est l’algorithme qui s’en occupe en s’auto-alimentant.

Définissons maintenant les entrées, la sortie et les paramètres de la fonction de compression unidirectionnelle dont \(\small m\) est la donnée originale complète à compresser.

  • \(\small i\) le nombre d’itérations à effectuer,
  • \(\small k\) la taille en bits des blocs de \(\small m\) et des condensats,
  • \(\small m_{i}\) le bloc de la i-ème itération,
  • \(\small H_{i-1}\) le condensat précédent,
  • \(\small H_{i}\) le condensat intermédiaire,
  • \(\small E_{m_{i}}\) le résultat de la fonction de chiffrement E traitant mi.
Construction de Davies-Meyer qui exploite le chiffrement symétrique par blocs pour construire une fonction de compression unidirectionnelle pouvant être utilisée dans une fonction de hachage.
Construction de Davies-Meyer – Wikipédia (modifié par mes soins)

La formule mathématique de la fonction de compression est \(\small H_{i} = E_{m_{i}}(H_{i-1}) \oplus H_{i-1}\) où \(\small \oplus\) représente l’opération « XOR » ou « OU exclusif » tel que :

Bit ABit BA \(\small \oplus\) B
000
101
011
110
Table de vérité de XOR

Étape 1 : division en blocs

On va d’abord diviser \(\small m\) en i blocs de k-bit, k étant aussi la taille des clés de la fonction de chiffrement. On ajoutera du padding (intégrant la taille de la donnée initiale) au dernier bloc si nécessaire afin de le compléter. i et k varient en fonction de la fonction SHA-2 utilisée.

Étape 2 : chiffrement symétrique

La première itération n’a évidemment pas de \(\small H_{i-1}\), il faut donc lui fournir un \(\small H_{-1}\) prédéfini de taille k. En cryptographie, on appelle ces valeurs des vecteurs d’initialisation (IV). On prend donc en entrée \(\small H_{-1}\) que l’on va chiffrer avec le premier bloc de la donnée à compresser soit \(\small m_{0}\), qui nous sert alors de clé. On obtiendra en sortie le chiffré \(\small E_{m_{0}}\).

Lors de la deuxième itération, on prendra en entrées \(\small H_{0}\) soit le résultat de la première compression passée par le XOR et \(\small m_{1}\), le deuxième bloc du message à compresser.

Étape 3 : opération XOR

Pour rendre E unidirectionnelle, on passe \(\small E_{m_{0}}\) dans la fonction XOR avec comme seconde entrée \(\small H_{-1}\) afin d’obtenir \(\small H_{0}\) qui sert immédiatement de nouvelle entrée à E. Et ainsi de suite jusqu’à i itérations et l’obtention du condensat final.

Quand ne pas utiliser SHA-2 ?

SHA-2 est vulnérable aux attaques de type « extension de la longueur », sauf pour SHA-512/224 et SHA-512/256. Il ne faut donc pas utiliser SHA-2 lorsqu’un secret entre en jeu notamment lors de l’emploi de codes d’authentification de message (MAC).

Liens à propos de SHA-2

Si vous voulez comprendre visuellement comment la mécanique interne de SHA-2 fonctionne, je vous recommande ce site, ou cette page qui est non interactive mais qui fournit plus d’explications. Pour vous divertir avec l’extension des condensats, j’ai trouvé un logiciel écrit en C à compiler sur votre machine.

Propriétaire et gestionnaire de Secnum.fr.

Site Footer