Implémentez l’algorithme de hachage SHA-1 en Python : Guide étape par étape
Introduction
L’algorithme SHA-1 (Secure Hash Algorithm 1) a été développé par la NSA en 1995 comme partie intégrante de la norme de signature numérique. Bien qu’autrefois largement utilisé, notamment dans SSL/TLS et pour la vérification de fichiers, SHA-1 a été progressivement abandonné en raison de ses vulnérabilités. À partir de 2005, des attaques pratiques montrant ses faiblesses ont conduit les experts en sécurité à recommander des alternatives telles que SHA-256. Malgré sa dépréciation, comprendre SHA-1 offre un aperçu précieux du fonctionnement des algorithmes de hachage.
Pré requis
Pour implémenter SHA-1 en Python, vous devrez avoir :
- Des connaissances de base en Python.
- Une compréhension des concepts cryptographiques de base tels que le hachage et la sécurité des données.
- Python installé sur votre machine, ainsi que tout éditeur de code de votre choix.
Comprendre le fonctionnement de SHA-1
L’algorithme SHA-1 transforme une entrée donnée en une empreinte de 160 bits. Voici comment il fonctionne :
Architecture de l’algorithme SHA-1
- Prise en entrée des données : SHA-1 accepte des entrées de toute longueur inférieure à 2^64 bits.
- Processus de transformation et d’agitation : L’input est réparti en blocs de taille gérable pour les transformations successives.
- Production de la valeur de hachage : Le résultat est une empreinte de 160 bits unique, difficile à inverser.
Composition et étapes de SHA-1
- Prétraitement des données (padding) : Les données sont complétées pour obtenir un multiple de 512 bits.
- Initialisation des constantes et variables : Les registres H0 à H4 sont initialisés avec des valeurs définies.
- Traitement par blocs de 512 bits : Chaque bloc est traité via une série de transformations.
- Fonctionnement de la rotation et des opérations logiques : SHA-1 utilise des opérations comme ROTL (rotation left) et divers opérateurs logiques.
- Endianness : Les données sont traitées dans un format Big Endian.
- Calcul final et concaténation des morceaux de hachage : Les registres de sortie sont combinés pour produire le hachage final.
Implémentation de SHA-1 en Python
Étape 1: Configurer votre environnement Python
Assurez-vous d’avoir Python installé. Installez des bibliothèques comme unittest pour le test ultérieur.
pip install unittest
Étape 2: Lire et prétraiter les données d’entrée
La première étape consiste à convertir l’entrée en binaire.
def pad_message(message):
message = bytearray(message, 'ascii')
original_len_bits = (8 * len(message)) & 0xFFFFFFFFFFFFFFFF
message.append(0x80)
while len(message) % 64 != 56:
message.append(0)
message += original_len_bits.to_bytes(8, 'big')
return message
Étape 3: Initialiser les variables de hachage
Définissez les valeurs initiales des registres.
H0 = 0x67452301 H1 = 0xEFCDAB89 H2 = 0x98BADCFE H3 = 0x10325476 H4 = 0xC3D2E1F0
Étape 4: Traitement itératif des blocs de données
Chaque bloc de 512 bits est transformé à l’aide de fonctions logiques spécifiques.
def process_blocks(message):
global H0, H1, H2, H3, H4
for i in range(0, len(message), 64):
w = list(int.from_bytes(message[j:j+4], 'big') for j in range(i, i + 64, 4))
for j in range(16, 80):
w.append(ROTL(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1))
a, b, c, d, e = H0, H1, H2, H3, H4
# 80 rounds on each block
for j in range(80):
if 0 <= j < 20:
f = (b & c) | (~b & d)
k = 0x5A827999
elif 20 <= j < 40:
f = b ^ c ^ d
k = 0x6ED9EBA1
elif 40 <= j < 60:
f = (b & c) | (b & d) | (c & d)
k = 0x8F1BBCDC
else:
f = b ^ c ^ d
k = 0xCA62C1D6
temp = (ROTL(a, 5) + f + e + k + w[j]) & 0xFFFFFFFF
e = d
d = c
c = ROTL(b, 30)
b = a
a = temp
H0 = (H0 + a) & 0xFFFFFFFF
H1 = (H1 + b) & 0xFFFFFFFF
H2 = (H2 + c) & 0xFFFFFFFF
H3 = (H3 + d) & 0xFFFFFFFF
H4 = (H4 + e) & 0xFFFFFFFF
def ROTL(n, b):
return ((n << b) | (n << (32 - b))) & 0xFFFFFFFF
<h4>Étape 5: Compilation des résultats</h4>
Transformez le résultat final en un format lisible (hexadécimal).
def sha1(message):
padded_msg = pad_message(message)
process_blocks(padded_msg)
hash_result = (H0 << 128) | (H1 << 96) | (H2 << 64) | (H3 << 32) | H4
return '{:040x}'.format(hash_result)
<h3>Test et validation de l'implémentation</h3>
Créez des cas de test pour comparer votre hachage SHA-1 avec des valeurs connues.
import unittest
class TestSHA1(unittest.TestCase):
def test_known_hash(self):
self.assertEqual(sha1("abc"), "a9993e364706816aba3e25717850c26c9cd0d89d")
if __name__ == '__main__':
unittest.main()
Erreurs courantes et solutions
- Erreur de padding : Veillez à bien compléter les données avec la bonne longueur.
- Gestion de l’endianess : Assurez-vous que les conversions suivent le format Big Endian.
Analyse de performances
En matière de performances, notre implémentation manuelle est plus lente par rapport à des bibliothèques optimisées comme hashlib. Cependant, cette approche éducative approfondit votre compréhension.
Conclusion
Ce tutoriel a détaillé la mise en œuvre de SHA-1 en Python, de la théorie à la pratique complète. Bien que déprécié, SHA-1 nous apprend énormément sur les algorithmes de hachage et leur importance en cryptographie, tout en soulignant la nécessité d’utiliser des alternatives plus sûres.
Ressources supplémentaires
FAQ
Puis-je utiliser SHA-1 pour les nouvelles applications ?
Non, SHA-1 est considéré comme dangereux pour de nouvelles applications en raison de ses vulnérabilités connues. Optez plutôt pour SHA-256 ou SHA-3.
Pourquoi implémenter SHA-1 à la main ?
Malgré sa dépréciation, réécrire SHA-1 vous aide à comprendre le fonctionnement interne des algorithmes de hachage et développe vos compétences en cryptographie.

