Casser des mots de passe
Se mettre à la place de l'attaquant
Pour bien défendre, il faut comprendre l'attaque. Imagine qu'une base de mots de passe hachés a fuité (la tienne, dans ton laboratoire, bien sûr). Les empreintes sont à sens unique... alors comment un attaquant retrouve-t-il les mots de passe ?
Il ne les « inverse » pas. Il devine : il essaie des mots de passe, les hache, et compare à la base. Si une empreinte calculée correspond à une empreinte de la base, il a trouvé le mot de passe.
Exercice : Un casseur par dictionnaire
Voici une base volée : des utilisateurs et l'empreinte SHA-256 de leur mot de passe. Et une liste de mots de passe courants. Écris casser(base, liste) qui renvoie un dictionnaire {utilisateur : mot de passe} pour tous les comptes dont le mot de passe est dans la liste.
Pour chaque utilisateur, essaie chaque mot de la liste : hache-le, et si l'empreinte correspond, tu as trouvé.
Voir une solution
import hashlib
base = {
"awa": "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
"paul": "e93e24c1b877a15df5e4a8cbb20f351b891b750779cf5e8fb99119a7142d89cf",
"mireille": "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8",
"junior": "d77d07912f337030a2972ac7b646dd1f78dadae789b806d2a2ad5fffb8fb9a5a",
"admin": "dcf8ad297a71852c220ce269f1986187823a05f0e7585ab27799a4036a4f641a",
}
liste = ["123456", "password", "azerty", "soleil", "000000", "admin", "qwerty", "motdepasse", "iloveyou", "dragon"]
def casser(base, liste):
"""Renvoie {utilisateur: mot de passe} pour les comptes cassés par la liste."""
trouves = {}
for utilisateur, empreinte in base.items():
for mot in liste:
if hashlib.sha256(mot.encode()).hexdigest() == empreinte:
trouves[utilisateur] = mot
break
return trouves
trouves = casser(base, liste)
print(trouves)
print(len(trouves), "comptes sur", len(base), "cassés")Dans l'appli, ton code est exécuté et corrigé automatiquement. Faire l'exercice
Deviner les variantes : les règles
Junior a résisté avec Douala2024. Mais ce mot de passe n'est pas vraiment solide : c'est un nom de ville plus une année. Les attaquants appliquent des règles à leurs listes : ajouter des chiffres, une année, une majuscule, remplacer a par @...
Avec une règle « mot du dictionnaire + année récente », Douala2024 tombe en quelques secondes. C'est la leçon la plus importante de cette partie :
Exercice : Mesurer le temps de cassage
Comprends pourquoi la longueur gagne. Pour un mot de passe fait de caractères pris dans un jeu de taille possibilités, il y a taille ** longueur combinaisons. Si un attaquant teste vitesse empreintes par seconde, le temps au pire est le nombre de combinaisons divisé par la vitesse.
Écris secondes_max(taille_jeu, longueur, vitesse) qui renvoie ce temps en secondes. Puis compare deux mots de passe face à un hashcat à 10 milliards d'essais par seconde :
t_court: 6 chiffres (jeu de 10, longueur 6) ;t_long: 12 caractères parmi 70 (minuscules, majuscules, chiffres, symboles).
Voir une solution
def secondes_max(taille_jeu, longueur, vitesse):
"""Temps au pire pour tout essayer, en secondes."""
return taille_jeu ** longueur / vitesse
vitesse = 10_000_000_000
t_court = secondes_max(10, 6, vitesse)
t_long = secondes_max(70, 12, vitesse)
print("6 chiffres :", round(t_court, 4), "secondes")
print("12 caracteres varies :", round(t_long / (3600 * 24 * 365), 1), "années")Dans l'appli, ton code est exécuté et corrigé automatiquement. Faire l'exercice