Skip to content

Commit ce9d50c

Browse files
committed
Correction de l'orchestrateur et ajustements correspondants
1 parent 148c920 commit ce9d50c

File tree

6 files changed

+78
-72
lines changed

6 files changed

+78
-72
lines changed

main.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from src.detecteur_crypto import DetecteurCryptoOrchestrateur
1+
from src.detecteur_crypto import DetecteurCryptoOrchestrateur, ResultatAnalyse
22
from src.analyzers.blowfish_analyzer import Blowfish_Analyzer
33
from src.analyzers.aes_cbc_analyzer import Aes_Cbc_Analyzer
44
from src.interface_console import consoleInterface
@@ -13,4 +13,5 @@
1313
# except FileNotFoundError:
1414
# print("Erreur: Le fichier 'mission3.enc' est introuvable.")
1515

16-
consoleInterface()
16+
consoleInterface()
17+
# print(DetecteurCryptoOrchestrateur().mission_complete_automatique('data/', 'keys/wordlist.txt'))

rapport_mission.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
RAPPORT DE SYNTHESE DU 05/08/25 � 00:01:06~ Mission 2: CHACHA20 ~ I - Statistiques relatives � l'analyse du fichier~Fichier crypt� par cet algorithme: mission1.enc~Cl� de d�chiffrement identifi�e: PK7 ~Nombre de tentatives: 127 ~Temps d'ex�cution: 368s ~ II - R�sultats obtenusTaux r�ussite du d�chiffrement: 97%(Succ�s)~Texte d�chiffr�: Je suis l�! ~
1+
RAPPORT DE SYNTHESE DU 11/08/25 � 04:19:59~ Mission 1: AES-CBC-256 ~ I - Statistiques relatives � l'analyse du fichier~-Fichier crypt� par cet algorithme: ('mission1.enc',)~-Cl� de d�chiffrement identifi�e: b'\xf7@[\xc1\xb5\x83c\xd8g?\xda\xcbO\xbd\rcZ\xfc\xfe\x9b\x0f\x88\r\xf1\x80\x89\xa1R\x0f\xd1f\xd8' ~-Nombre de tentatives: 1 ~-Temps d'ex�cution: 0.013037919998168945 ~ II - R�sultats obtenus~-Taux r�ussite du d�chiffrement: 69.42(Succ�s)~-Texte d�chiffr�: F�licitations ! Vous avez d�chiffr� la mission 1.~Le secret de cette mission est : AES-256-CBC est toujours largement utilis� dans l'industrie.~Cl� utilis�e : paris2024~Algorithme : AES-256-CBC avec PBKDF2 ~~RAPPORT DE SYNTHESE DU 11/08/25 � 04:19:59~ Mission 3: BLOWFISH ~ I - Statistiques relatives � l'analyse du fichier~-Fichier crypt� par cet algorithme: ('mission3.enc',)~-Cl� de d�chiffrement identifi�e: b'' ~-Nombre de tentatives: 15 ~-Temps d'ex�cution: 0.010114669799804688 ~ II - R�sultats obtenus~-Taux r�ussite du d�chiffrement: 0(Echec)~-Texte d�chiffr�: b'' ~~RAPPORT DE SYNTHESE DU 11/08/25 � 04:19:59~ Mission 5: FERNET ~ I - Statistiques relatives � l'analyse du fichier~-Fichier crypt� par cet algorithme: ('mission5.enc',)~-Cl� de d�chiffrement identifi�e: b"i'\xaaf\x99\xdc\xa0A\xed\xc6\xce\xfe`\xcc\xb9/\xf8\xa1\x0e~\x18\xd3\xbb\xeb\xa1\x9f\xc0|\xc8\xf1_\xdd" ~-Nombre de tentatives: 2 ~-Temps d'ex�cution: 0.016638517379760742 ~ II - R�sultats obtenus~-Taux r�ussite du d�chiffrement: 66.0(Succ�s)~-Texte d�chiffr�: Magnifique ! Derni�re mission compl�t�e.~Message final : j'adore la cryptographie~Cette phrase �tait la cl� elle-m�me !~Algorithme : Fernet (bas� sur AES-128-CBC + HMAC) ~~

src/detecteur_crypto.py

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,24 @@
1010
from src.analyzers.blowfish_analyzer import Blowfish_Analyzer
1111
from src.analyzers.aes_gcm_analyzer import Aes_Gcm_Analyzer
1212
from src.analyzers.fernet_analyzer import FernetAnalyzer
13-
from src.rapport_mission import generer_rapport_mission
13+
from src.rapport_mission import rapport_mission
1414

1515
# Import des modules utilitaries
16-
from src.utils import est_dechiffre
16+
from src.utils import verifier_texte_dechiffre
1717

1818
class ResultatAnalyse:
1919
"""
2020
Classe représentant un résultat d'analyse.
2121
"""
22-
def __init__(self, algo: str, cle: bytes, score_probabilite: float, texte_dechiffre: bytes, temps_execution: float = 0.0, nb_tentatives: int = 0):
22+
def __init__(self, algo: str, cle: bytes, score_probabilite: float, texte_dechiffre: bytes, temps_execution: float = 0.0, nb_tentatives: int = 0, fichier: str ='', taux_succes: float = 0.0):
2323
self.algo = algo
2424
self.cle = cle
2525
self.score_probabilite = score_probabilite
2626
self.texte_dechiffre = texte_dechiffre
2727
self.temps_execution = temps_execution
2828
self.nb_tentatives = nb_tentatives
29-
29+
self.fichier = fichier,
30+
self.taux_succes = taux_succes
3031
class DetecteurCryptoOrchestrateur:
3132
"""
3233
Classe principale qui centralise tout:
@@ -40,7 +41,7 @@ def __init__(self):
4041
Initialisation de tous les modules d'analyse disponibles
4142
"""
4243
self.analyzers: dict[str, CryptoAnalyzer] = {
43-
"AES-CBC": Aes_Cbc_Analyzer(),
44+
"AES-CBC-256": Aes_Cbc_Analyzer(),
4445
"ChaCha20": ChaCha20_Analyzer(),
4546
"Blowfish": Blowfish_Analyzer(),
4647
"AES-GCM": Aes_Gcm_Analyzer(),
@@ -89,7 +90,7 @@ def analyser_fichier_specifique(self, chemin_fichier_chiffre: str) -> ResultatAn
8990
scores_algorithmes[nom_algo] = score
9091
# print(f"{nom_algo}: score {score:.2f}")
9192

92-
if score > 0.5: # Seuil de confiance
93+
if score > 0.9 : # Seuil de confiance
9394
algorithme_detecte = nom_algo
9495
score_probabilite = score
9596
# print(f"Algorithme détecté: {algorithme_detecte} (score: {score:.2f})")
@@ -98,32 +99,35 @@ def analyser_fichier_specifique(self, chemin_fichier_chiffre: str) -> ResultatAn
9899
if not algorithme_detecte:
99100
print("Aucun algorithme correctement détecté ")
100101
temps_execution = time.time() - debut_analyse
101-
return ResultatAnalyse("", b"", 0.0, b"", temps_execution, nb_tentatives)
102+
return ResultatAnalyse("", b"", 0.0, b"", temps_execution, nb_tentatives, chemin_fichier_chiffre, 0)
102103

103104
temps_execution = time.time() - debut_analyse
104105

105-
return ResultatAnalyse(algorithme_detecte, cle, score_probabilite, texte_dechiffre, temps_execution, nb_tentatives)
106+
return ResultatAnalyse(algorithme_detecte, cle, score_probabilite, texte_dechiffre, temps_execution, nb_tentatives, chemin_fichier_chiffre, 0)
106107

107108
except Exception as e:
108109
print(f"Erreur lors de l'analyse: {str(e)}")
109110
temps_execution = time.time() - debut_analyse
110-
return ResultatAnalyse("", b"", 0.0, b"", temps_execution, 0)
111+
return ResultatAnalyse("", b"", 0.0, b"", temps_execution, 0, chemin_fichier_chiffre)
111112

112113
def __tenter_dechiffrement_avec_dictionnaire(self, chemin_fichier: str, cles_candidates: list[bytes], analyzer: CryptoAnalyzer, resultat: ResultatAnalyse):
113114
for j, cle in enumerate(cles_candidates):
114115
resultat.nb_tentatives += 1
115116

116117
if j % 100 == 0: # retour visuel tous les 100 essais
117-
print(f" Tentative {j+1}/{len(cles_candidates)}...")
118+
print(f"Tentative {j+1}/{len(cles_candidates)}...")
118119

119-
texte_dechiffre = analyzer.dechiffrer(chemin_fichier, cle)
120-
if texte_dechiffre and est_dechiffre(texte_dechiffre.decode('utf-8')) and len(texte_dechiffre) > 0:
120+
texte_dechiffre = analyzer.dechiffrer(chemin_fichier, cle).decode('utf-8')
121+
succes = verifier_texte_dechiffre(texte_dechiffre)['taux_succes']
122+
123+
if texte_dechiffre and succes > 60 and len(texte_dechiffre) > 0:
121124
resultat.cle = cle
122125
resultat.texte_dechiffre = texte_dechiffre
123-
print(f" Clé trouvée après {j+1} tentatives!")
124-
break
125-
else:
126-
print("Aucune clé valide trouvée")
126+
resultat.taux_succes = succes
127+
print(f"Clé trouvée après {j+1} tentatives!")
128+
return
129+
130+
print("Aucune clé valide trouvée")
127131

128132
def mission_complete_automatique(self, dossier_chiffres: str, chemin_dictionnaire: str) -> List[ResultatAnalyse]:
129133
"""
@@ -153,8 +157,9 @@ def mission_complete_automatique(self, dossier_chiffres: str, chemin_dictionnair
153157
print(f"{len(fichiers_enc)} fichiers .enc détectés")
154158
print("\nANALYSE SÉQUENTIELLE DES FICHIERS")
155159

156-
for i, fichier in enumerate(fichiers_enc, 1):
157-
print(f"\nFICHIER {i}/{len(fichiers_enc)}: {fichier}")
160+
for i, fichier in enumerate(fichiers_enc, 0):
161+
162+
print(f"\nFICHIER {i+1}/{len(fichiers_enc)}: {fichier}")
158163

159164
chemin_fichier = os.path.join(dossier_chiffres, fichier)
160165

@@ -179,12 +184,23 @@ def mission_complete_automatique(self, dossier_chiffres: str, chemin_dictionnair
179184

180185
# retour visuel
181186
if resultat.algo:
182-
print(f"{fichier}: {resultat.algo} (score: {resultat.score_probabilite:.2f})")
187+
print(f"{fichier}: {resultat.algo} (score: {resultat.score_probabilite:.2f}) \n\n")
183188
else:
184189
print(f"{fichier}: Aucun algorithme détecté")
185190

186191
# Rapport de synthèse final
187-
generer_rapport_mission().generer_rapport_synthese(resultats, time.time() - debut_mission)
192+
for i in range(6) :
193+
resultat = {
194+
'algorithme': resultats[i].algo,
195+
'fichier': resultats[i].fichier,
196+
'cle': resultats[i].cle,
197+
'tentatives': resultats[i].nb_tentatives,
198+
'temps_execution': resultats[i].temps_execution,
199+
'taux_succes': resultats[i].taux_succes,
200+
'statut_succes' : 'Succès' if resultats[i].taux_succes > 60 else 'Echec',
201+
'texte_dechiffre' : resultats[i].texte_dechiffre
202+
}
203+
rapport_mission().generer_rapport_synthese(resultat)
188204

189205
# Mise à jour des statistiques globales
190206
self.missions_completees.append({
@@ -256,3 +272,4 @@ def attaque_dictionnaire_manuelle(self, chemin_fichier: str, algorithme_choisi:
256272
return ResultatAnalyse("", b"", 0.0, b"", temps_execution, 0)
257273

258274
# print(DetecteurCryptoOrchestrateur().analyser_fichier_specifique(f"{os.path.abspath(os.curdir)}\\CryptoForensic-Python\\data\\mission2.enc"))
275+

src/interface_console.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import re
12
from rich.console import Console
23
from rich.traceback import install
34
from rich.markdown import Markdown
@@ -9,6 +10,7 @@
910
# from detecteur_crypto import Analyser_fichier_uniquement
1011
# from detecteur_crypto import Analyser_fichier_sequentiels
1112
from .detecteur_crypto import DetecteurCryptoOrchestrateur
13+
from .rapport_mission import rapport_mission
1214
import time, os
1315

1416
install()
@@ -144,15 +146,26 @@ def menu_4(self):
144146
self.console.clear()
145147
self.dynamiqueText("Affichage des rapports","green")
146148
time.sleep(0.02)
147-
f = open("rapport_mission.txt",'r')
148-
rapports = f.read()
149-
for rapport in rapports:
150-
print(f"\n{rapport}")
151-
f.close()
149+
date = input("Quel est la date du rapport que vous souhaitez? Entrez 'all' pour tous les rapports. (format: jj/mm/aa): ")
150+
151+
rapports = []
152+
if date == "all" :
153+
with open("rapport_mission.txt",'r') as f :
154+
rapports = f.readlines()
155+
f.close()
156+
elif re.match(r"\d+/\d+/\d+", date) :
157+
rapports = rapport_mission().recuperer_ancien_rapport(date)
158+
159+
if rapports :
160+
for rapport in rapports:
161+
print(f"\n{rapport.replace('~', '\n')}")
162+
else :
163+
self.console.print(Markdown('#### Aucun rapport trouvé.'))
164+
165+
time.sleep(0.03)
152166
esc = input('Veuillez appuyez sur la touche entrer pour continuer')
153-
if esc=='':
167+
if esc=="":
154168
self.default_menu()
155-
else: self.default_menu()
156169

157170
def menu_5(self):
158171
self.console.clear()
@@ -217,4 +230,4 @@ def menu_6(self):
217230
time.sleep(2)
218231
self.console.clear()
219232

220-
consoleInterface()
233+
# consoleInterface()

src/rapport_mission.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from datetime import date, datetime
22
import os
33
from pathlib import Path
4-
class generer_rapport_mission():
4+
class rapport_mission():
55

66
def __init__(self):
77
pass
@@ -18,19 +18,20 @@ def generer_rapport_synthese(self, resultats_de_mission:dict)->None:
1818
equivalence=['AES-CBC-256', 'CHACHA20', 'BLOWFISH', 'AES-GCM', 'FERNET']
1919

2020
try :
21-
rapport= f"RAPPORT DE SYNTHESE DU {date.today().strftime("%d/%m/%y")} à {str(datetime.now().time()).split('.')[0]}\n " f"Mission {equivalence.index(resultats_de_mission['algorithme'].upper()) + 1}: {resultats_de_mission['algorithme'].upper()} \n I - Statistiques relatives à l'analyse du fichier\n" f"Fichier crypté par cet algorithme: {resultats_de_mission['fichier']}\n" f"Clé de déchiffrement identifiée: {resultats_de_mission['cle']} \n" f"Nombre de tentatives: {resultats_de_mission['tentatives']} \n" f"Temps d'exécution: {resultats_de_mission["temps_execution"]} \n II - Résultats obtenus" f"Taux réussite du déchiffrement: {resultats_de_mission['taux_succes']}({resultats_de_mission['statut_succes']})\n" f"Texte déchiffré: {resultats_de_mission['texte_dechiffre']} \n"
21+
rapport= f"RAPPORT DE SYNTHESE DU {date.today().strftime("%d/%m/%y")} à {str(datetime.now().time()).split('.')[0]}\n " f"Mission {equivalence.index(resultats_de_mission['algorithme'].upper()) + 1}: {resultats_de_mission['algorithme'].upper()} \n I - Statistiques relatives à l'analyse du fichier\n" f"-Fichier crypté par cet algorithme: {resultats_de_mission['fichier']}\n" f"-Clé de déchiffrement identifiée: {resultats_de_mission['cle']} \n" f"-Nombre de tentatives: {resultats_de_mission['tentatives']} \n" f"-Temps d'exécution: {resultats_de_mission["temps_execution"]} \n II - Résultats obtenus\n" f"-Taux réussite du déchiffrement: {resultats_de_mission['taux_succes']}({resultats_de_mission['statut_succes']})\n" f"-Texte déchiffré: {resultats_de_mission['texte_dechiffre']} \n\n"
2222

2323
# Ecriture du rapport dans le fichier rapport.txt pour les affichage ultérieurs
2424
chemin = Path(f"rapport_mission.txt")
2525
with open(chemin, 'a') as f:
2626
f.write(rapport.replace('\n', '~'))
27-
f.close()
28-
29-
return rapport
27+
f.close()
28+
print(rapport)
29+
30+
return
3031
except (KeyError, ValueError):
31-
print("Une erreur s'est produite.")
32+
print("Une erreur s'est produite.")
33+
return
3234

33-
return rapport
3435

3536

3637
def recuperer_ancien_rapport(self, base_date:str)->list|str:
@@ -44,15 +45,15 @@ def recuperer_ancien_rapport(self, base_date:str)->list|str:
4445
4546
4647
"""
47-
rapport=[]
48+
rapports=[]
4849
try:
4950
chemin = Path(f"rapport_mission.txt")
5051
with open(chemin, 'r') as f:
5152
for line in f:
5253
if line.find(base_date) != -1:
53-
rapport.append(line.replace('~', '\n'))
54+
rapports.append(line.replace('~', '\n'))
5455
f.close()
55-
return rapport if rapport else 'Aucun rapport trouvé à cette date.'
56+
return rapports if rapports else False
5657
except FileNotFoundError:
5758
print('Fichier non trouvé')
5859

src/utils.py

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,35 +32,6 @@ def calculer_entropie(bytes: bytes) -> float:
3232
proba_byte = 1 / i
3333
entropie += (proba_byte) * math.log(1/proba_byte, 8)
3434
return entropie
35-
36-
37-
38-
def est_dechiffre(texte:str) -> bool:
39-
"""
40-
Détermine si oui ou non une chaine a été déchiffrée
41-
42-
Args:
43-
texte(str): la chaine en supposée déchiffrée
44-
Returns:
45-
bool: déchiffrée ou non
46-
"""
47-
stats:dict[str, Any] = verifier_texte_dechiffre(texte)
48-
pourcent=0
49-
50-
# Les caractères imprimables constituent 50% de la validation du déchiffrement
51-
if stats['imprimable'] > 70 :
52-
pourcent += 50
53-
54-
# Le pourcentage de mots validés par les dictionnaires en constitue 30%
55-
if stats['p_mots_valide'] > 50 :
56-
pourcent += 30
57-
58-
# Le respect de la ponctuation, les 20% restants
59-
if stats['ponctuation_valide'] > 50 :
60-
pourcent += 20
61-
62-
return True if pourcent > 80 else False
63-
6435

6536

6637
def verifier_texte_dechiffre(texte: str) -> Dict[str, Any]:
@@ -86,7 +57,8 @@ def verifier_texte_dechiffre(texte: str) -> Dict[str, Any]:
8657
'nombre_mots':0,
8758
'p_mots_valide':0,
8859
'non_mots':[],
89-
'ponctuation_valide':0
60+
'ponctuation_valide':0,
61+
'taux_succes':0
9062
}
9163

9264
if not texte:
@@ -139,7 +111,7 @@ def verifier_texte_dechiffre(texte: str) -> Dict[str, Any]:
139111
stats['p_mots_valide'] = round((mots_valides / len(mots)) * 100, 2)
140112
else:
141113
stats['p_mots_valide'] = 0.0
142-
114+
143115
except Exception:
144116
raise
145117

@@ -158,6 +130,8 @@ def verifier_texte_dechiffre(texte: str) -> Dict[str, Any]:
158130
if not nbr_points: nbr_points=1
159131
stats['ponctuation_valide'] = round(count*100/nbr_points, 2)
160132

133+
stats['taux_succes'] = round((stats['imprimable'] + stats['p_mots_valide'] + stats['ponctuation_valide']) / 3, 2)
134+
161135
return stats
162136

163137

0 commit comments

Comments
 (0)