From 80c1f1b10606b12f0b9376c044a63c425c881a0a Mon Sep 17 00:00:00 2001 From: Eunock-web Date: Sat, 2 Aug 2025 06:20:34 +0200 Subject: [PATCH 01/14] =?UTF-8?q?Int=C3=A9gration=20de=20AesCbcAnalyzer=20?= =?UTF-8?q?dans=20DetecteurCryptoOrchestrateur.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/detecteur_crypto.py | 104 +++++++++++++++++++++++++++++++++++----- 1 file changed, 93 insertions(+), 11 deletions(-) diff --git a/src/detecteur_crypto.py b/src/detecteur_crypto.py index 45c6775..ef27e8f 100644 --- a/src/detecteur_crypto.py +++ b/src/detecteur_crypto.py @@ -1,17 +1,99 @@ -import AesCbcAnalyzer -from crypto_analyzer import identifier_algo +# Import des modules +import os + +# Import des modules d'analyse +from .analyzers.aes_cbc_analyzer import Aes_Cbc_Analyzer + +class ResultatAnalyse: + """ + Classe représentant un résultat d'analyse. + """ + def __init__(self, algo: str, cle: bytes, texte_dechiffre: bytes): + self.algo = algo + self.cle = cle + self.texte_dechiffre = texte_dechiffre -""" - Classe principale qui centralise tout: - -Lance l’analyse des fichiers et identifie l'algorithme probable, - -Lance les attaquespar dictionnaire, - -Lance et coordonnes le processus de dechiffrement -""" class DetecteurCryptoOrchestrateur: """ - Initialisation de l'analyseur AES-CBC + Classe principale qui centralise tout: + -Lance l'analyse des fichiers et identifie l'algorithme probable, + -Lance les attaques par dictionnaire, + -Lance et coordonnes le processus de dechiffrement """ + def __init__(self): - self.aes_cbc_analyzer = AesCbcAnalyzer() - + """ + Initialisation de tous les modules d'analyse disponibles (AES-CBC) pour le moment + """ + self.analyzers = { + "AES-CBC": Aes_Cbc_Analyzer(), + } + def Analyser_fichier_uniquement(self, chemin_fichier_chiffre: str) -> ResultatAnalyse: + """ + Analyse un seul fichier chiffré et retourne le résultat de l'analyse. + + Args: + chemin_fichier_chiffre(str): chemin du fichier chiffré à analyser + + Returns: + ResultatAnalyse: résultat de l'analyse + """ + try: + #Initialisation des variables + algorithme_detecte = "" + cle = b"" + texte_dechiffre = b"" + + #Parcours des algorithmes disponibles + for nom_algo, analyzer in self.analyzers.items(): + score_probabilite = analyzer.identifier_algo(chemin_fichier_chiffre) # ← Retourne un float + print(f"{nom_algo}: score {score_probabilite:.2f}") + + if score_probabilite > 0.5: # ← Comparaison correcte avec le seuil + algorithme_detecte = nom_algo # ← Stockage du nom de l'algorithme + print(f"Algorithme détecté: {algorithme_detecte} (score: {score_probabilite:.2f})") + + # Génération des clés candidates + cles_candidates = analyzer.generer_cles_candidates("dicoEn") + print(f"{len(cles_candidates)} clés candidates générées") + + # Test de déchiffrement avec la première clé (pour l'exemple) + if cles_candidates: + texte_dechiffre = analyzer.dechiffrer(chemin_fichier_chiffre, cles_candidates[0]) + if texte_dechiffre: + cle = cles_candidates[0] + print("Déchiffrement réussi avec la première clé!") + else: + print("Déchiffrement échoué avec la première clé") + break + + if not algorithme_detecte: + print("Aucun algorithme détecté avec confiance suffisante") + + return ResultatAnalyse(algorithme_detecte, cle, texte_dechiffre) + except Exception as e: + print(f"Erreur lors de l'analyse du fichier {chemin_fichier_chiffre}: {str(e)}") + return ResultatAnalyse("", b"", b"") + + + def Analyser_fichiers_sequentiels(self, dossier_chiffres: str) -> list[ResultatAnalyse]: + """ + Analyse plusieurs fichiers chiffrés dans un dossier et retourne les résultats de l'analyse. + + Args: + dossier_chiffres(str): dossier contenant les fichiers chiffrés à analyser + + Returns: + list[ResultatAnalyse]: liste des résultats d'analyse pour chaque fichier + """ + try: + resultats = [] + for fichier_chiffre in os.listdir(dossier_chiffres): + chemin_fichier_chiffre = os.path.join(dossier_chiffres, fichier_chiffre) + resultat = self.Analyser_fichier_uniquement(chemin_fichier_chiffre) + resultats.append(resultat) + return resultats + except Exception as e: + print(f"Erreur lors de l'analyse des fichiers: {str(e)}") + return [] \ No newline at end of file From a41256c29fe1093e8f9e67072cffdf19d0ef6683 Mon Sep 17 00:00:00 2001 From: Eunock-web Date: Sat, 2 Aug 2025 16:38:41 +0200 Subject: [PATCH 02/14] Debut de l'implementation du code dans la classe principale avec le menu --- src/detecteur_crypto.py | 6 +-- src/interface_console.py | 80 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/src/detecteur_crypto.py b/src/detecteur_crypto.py index ef27e8f..8e25c99 100644 --- a/src/detecteur_crypto.py +++ b/src/detecteur_crypto.py @@ -47,11 +47,11 @@ def Analyser_fichier_uniquement(self, chemin_fichier_chiffre: str) -> ResultatAn #Parcours des algorithmes disponibles for nom_algo, analyzer in self.analyzers.items(): - score_probabilite = analyzer.identifier_algo(chemin_fichier_chiffre) # ← Retourne un float + score_probabilite = analyzer.identifier_algo(chemin_fichier_chiffre) # Retourne un float print(f"{nom_algo}: score {score_probabilite:.2f}") - if score_probabilite > 0.5: # ← Comparaison correcte avec le seuil - algorithme_detecte = nom_algo # ← Stockage du nom de l'algorithme + if score_probabilite > 0.5: # Comparaison correcte avec le seuil + algorithme_detecte = nom_algo # Stockage du nom de l'algorithme print(f"Algorithme détecté: {algorithme_detecte} (score: {score_probabilite:.2f})") # Génération des clés candidates diff --git a/src/interface_console.py b/src/interface_console.py index 5f8b70b..8e91cfe 100644 --- a/src/interface_console.py +++ b/src/interface_console.py @@ -3,6 +3,8 @@ from rich.markdown import Markdown from rich import print from rich.prompt import Prompt +from detecteur_crypto import Analyser_fichier_uniquement +from detecteur_crypto import Analyser_fichier_sequentiels import time, os install() @@ -50,7 +52,81 @@ def default_menu(self): self.console.print(menuTag,menuOption) time.sleep(0.04) - self.prompt.ask("Veuillez choisir une option ",choices=["1","2","3","4","5","6"]) + choix = self.prompt.ask("Veuillez choisir une option ",choices=["1","2","3","4","5","6"]) + if choix == "1": + self.menu_1() + elif choix == "2": + self.menu_2() + elif choix == "3": + self.menu_3() + elif choix == "4": + self.menu_4() + elif choix == "5": + self.menu_5() + elif choix == "6": + self.menu_6() -consoleInterface() \ No newline at end of file + def menu_1(self): + self.console.clear() + self.dynamiqueText("Analyse d'un fichier spécifique","green") + self.dynamiqueText("Veuillez entrer le chemin du fichier :","white") + time.sleep(0.04) + chemin_fichier = self.prompt.ask("Veuillez entrer le chemin du fichier : ") + resultat = Analyser_fichier_uniquement(self,chemin_fichier) + self.console.clear() + self.dynamiqueText("Analyse en cours...","green") + time.sleep(0.04) + self.console.clear() + self.dynamiqueText("Analyse terminée","green") + time.sleep(0.04) + self.default_menu() + + def menu_2(self): + self.console.clear() + self.dynamiqueText("Mission complète automatique","green") + self.dynamiqueText("Veuillez entrer le chemin du dossier :","white") + time.sleep(0.04) + chemin_dossier = self.prompt.ask("Veuillez entrer le chemin du dossier : ") + self.console.clear() + self.dynamiqueText("Mission en cours...","green") + time.sleep(0.04) + self.console.clear() + self.dynamiqueText("Mission terminée","green") + time.sleep(0.04) + self.default_menu() + + def menu_3(self): + self.console.clear() + self.dynamiqueText("Attaque par dictionnaire manuelle","green") + self.dynamiqueText("Veuillez entrer le chemin du fichier :","white") + time.sleep(0.04) + chemin_fichier = self.prompt.ask("Veuillez entrer le chemin du fichier : ") + self.console.clear() + self.dynamiqueText("Attaque en cours...","green") + time.sleep(0.04) + self.console.clear() + self.dynamiqueText("Attaque terminée","green") + time.sleep(0.04) + self.default_menu() + + def menu_4(self): + self.console.clear() + self.dynamiqueText("Affichage des rapports","green") + time.sleep(0.04) + self.default_menu() + + def menu_5(self): + self.console.clear() + self.dynamiqueText("Système d'aide intégré","green") + time.sleep(0.04) + self.default_menu() + + def menu_6(self): + self.console.clear() + self.dynamiqueText("Au revoir !","green") + time.sleep(0.04) + self.console.clear() + self.console.exit() + +consoleInterface() From cac3bf59d22738e187a90332460fa2bd42f20187 Mon Sep 17 00:00:00 2001 From: Eunock-web Date: Sat, 2 Aug 2025 16:50:56 +0200 Subject: [PATCH 03/14] Suite de l'implementation du code dans la classe principale avec le menu --- src/interface_console.py | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/interface_console.py b/src/interface_console.py index 8e91cfe..0eb9537 100644 --- a/src/interface_console.py +++ b/src/interface_console.py @@ -53,19 +53,27 @@ def default_menu(self): time.sleep(0.04) choix = self.prompt.ask("Veuillez choisir une option ",choices=["1","2","3","4","5","6"]) - if choix == "1": - self.menu_1() - elif choix == "2": - self.menu_2() - elif choix == "3": - self.menu_3() - elif choix == "4": - self.menu_4() - elif choix == "5": - self.menu_5() - elif choix == "6": - self.menu_6() - + try: + if choix == "1": + self.menu_1() + elif choix == "2": + self.menu_2() + elif choix == "3": + self.menu_3() + elif choix == "4": + self.menu_4() + elif choix == "5": + self.menu_5() + elif choix == "6": + self.menu_6() + + while choix > "6" or choix < "1": + self.console.print("Veuillez entrer un nombre entre 1 et 6") + choix = self.prompt.ask("Veuillez choisir une option ",choices=["1","2","3","4","5","6"]) + except ValueError: + self.console.print("Veuillez entrer un nombre entre 1 et 6") + except Exception as e: + self.console.print(f"Une erreur est survenue : {e}") def menu_1(self): self.console.clear() @@ -73,7 +81,7 @@ def menu_1(self): self.dynamiqueText("Veuillez entrer le chemin du fichier :","white") time.sleep(0.04) chemin_fichier = self.prompt.ask("Veuillez entrer le chemin du fichier : ") - resultat = Analyser_fichier_uniquement(self,chemin_fichier) + resultat = Analyser_fichier_uniquement(chemin_fichier) self.console.clear() self.dynamiqueText("Analyse en cours...","green") time.sleep(0.04) From 93fd27d840c1ee137beea52b504e30781c00f978 Mon Sep 17 00:00:00 2001 From: wesley-kami Date: Mon, 4 Aug 2025 16:55:26 +0100 Subject: [PATCH 04/14] Update de l'option quitter --- src/interface_console.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/interface_console.py b/src/interface_console.py index 0eb9537..fee6eb5 100644 --- a/src/interface_console.py +++ b/src/interface_console.py @@ -3,8 +3,8 @@ from rich.markdown import Markdown from rich import print from rich.prompt import Prompt -from detecteur_crypto import Analyser_fichier_uniquement -from detecteur_crypto import Analyser_fichier_sequentiels +# from detecteur_crypto import Analyser_fichier_uniquement +# from detecteur_crypto import Analyser_fichier_sequentiels import time, os install() @@ -39,7 +39,7 @@ def dynamiqueText(self,text,color): def default_menu(self): self.console.clear() - self.dynamiqueText("😈​ Bienvenue sur Forensic je suis Crypto votre assitant IA minimaliste🤖​ ","green") + self.dynamiqueText("😈​ Bienvenue sur Forensic je suis Crypto votre assitant IA minimaliste 🤖​ ","green") self.dynamiqueText("En quoi puis-je vous aider ? :","white") time.sleep(0.04) menuTag = Markdown("# Menu",style="blue") @@ -80,22 +80,22 @@ def menu_1(self): self.dynamiqueText("Analyse d'un fichier spécifique","green") self.dynamiqueText("Veuillez entrer le chemin du fichier :","white") time.sleep(0.04) - chemin_fichier = self.prompt.ask("Veuillez entrer le chemin du fichier : ") - resultat = Analyser_fichier_uniquement(chemin_fichier) + # chemin_fichier = self.prompt.ask("Veuillez entrer le chemin du fichier : ") + # resultat = Analyser_fichier_uniquement(chemin_fichier) self.console.clear() self.dynamiqueText("Analyse en cours...","green") time.sleep(0.04) self.console.clear() self.dynamiqueText("Analyse terminée","green") time.sleep(0.04) - self.default_menu() + # def menu_2(self): self.console.clear() self.dynamiqueText("Mission complète automatique","green") self.dynamiqueText("Veuillez entrer le chemin du dossier :","white") time.sleep(0.04) - chemin_dossier = self.prompt.ask("Veuillez entrer le chemin du dossier : ") + # chemin_dossier = self.prompt.ask("Veuillez entrer le chemin du dossier : ") self.console.clear() self.dynamiqueText("Mission en cours...","green") time.sleep(0.04) @@ -109,7 +109,7 @@ def menu_3(self): self.dynamiqueText("Attaque par dictionnaire manuelle","green") self.dynamiqueText("Veuillez entrer le chemin du fichier :","white") time.sleep(0.04) - chemin_fichier = self.prompt.ask("Veuillez entrer le chemin du fichier : ") + # chemin_fichier = self.prompt.ask("Veuillez entrer le chemin du fichier : ") self.console.clear() self.dynamiqueText("Attaque en cours...","green") time.sleep(0.04) @@ -132,9 +132,8 @@ def menu_5(self): def menu_6(self): self.console.clear() - self.dynamiqueText("Au revoir !","green") - time.sleep(0.04) + self.dynamiqueText("😄​ Merci pour votre visite et à la revoyure 👋​ !","yellow") + time.sleep(2) self.console.clear() - self.console.exit() consoleInterface() From c1c0b228cfbaedd2c2a697046f4996e3c5882096 Mon Sep 17 00:00:00 2001 From: Eunock-web Date: Tue, 5 Aug 2025 03:14:34 +0200 Subject: [PATCH 05/14] Revu des fonctions pour une meilleure optimisation --- src/detecteur_crypto.py | 248 ++++++++++++++++++++++++++++++++-------- 1 file changed, 200 insertions(+), 48 deletions(-) diff --git a/src/detecteur_crypto.py b/src/detecteur_crypto.py index 8e25c99..32a68fb 100644 --- a/src/detecteur_crypto.py +++ b/src/detecteur_crypto.py @@ -1,5 +1,7 @@ # Import des modules import os +import time +from typing import List # Import des modules d'analyse from .analyzers.aes_cbc_analyzer import Aes_Cbc_Analyzer @@ -8,10 +10,13 @@ class ResultatAnalyse: """ Classe représentant un résultat d'analyse. """ - def __init__(self, algo: str, cle: bytes, texte_dechiffre: bytes): + def __init__(self, algo: str, cle: bytes, score_probabilite: float, texte_dechiffre: bytes, temps_execution: float = 0.0, nb_tentatives: int = 0): self.algo = algo self.cle = cle + self.score_probabilite = score_probabilite self.texte_dechiffre = texte_dechiffre + self.temps_execution = temps_execution + self.nb_tentatives = nb_tentatives class DetecteurCryptoOrchestrateur: """ @@ -28,72 +33,219 @@ def __init__(self): self.analyzers = { "AES-CBC": Aes_Cbc_Analyzer(), } + self.missions_completees = [] + self.statistiques_globales = { + "total_fichiers": 0, + "fichiers_dechiffres": 0, + "temps_total": 0.0, + "tentatives_total": 0 + } - def Analyser_fichier_uniquement(self, chemin_fichier_chiffre: str) -> ResultatAnalyse: + def analyser_fichier_specifique(self, chemin_fichier_chiffre: str) -> ResultatAnalyse: """ - Analyse un seul fichier chiffré et retourne le résultat de l'analyse. - - Args: - chemin_fichier_chiffre(str): chemin du fichier chiffré à analyser - - Returns: - ResultatAnalyse: résultat de l'analyse + ANALYSE D'UN FICHIER SPÉCIFIQUE + - Sélection du fichier à analyser + - Identification automatique de l'algorithme + - Affichage des scores de probabilité + + Args: + chemin_fichier_chiffre(str): chemin du fichier chiffré à analyser + + Returns: + ResultatAnalyse: résultat de l'analyse """ + debut_analyse = time.time() + try: - #Initialisation des variables + # Vérification de l'existence du fichier + if not os.path.exists(chemin_fichier_chiffre): + print("Erreur: Fichier non trouvé") + return ResultatAnalyse("", b"", 0.0, b"", 0.0, 0) + + # Initialisation des variables algorithme_detecte = "" cle = b"" + score_probabilite = 0.0 texte_dechiffre = b"" + nb_tentatives = 0 - #Parcours des algorithmes disponibles + # Parcours des algorithmes disponibles + scores_algorithmes = {} for nom_algo, analyzer in self.analyzers.items(): - score_probabilite = analyzer.identifier_algo(chemin_fichier_chiffre) # Retourne un float - print(f"{nom_algo}: score {score_probabilite:.2f}") + score = analyzer.identifier_algo(chemin_fichier_chiffre) + scores_algorithmes[nom_algo] = score + print(f"{nom_algo}: score {score:.2f}") + + if score > 0.5: # Seuil de confiance + algorithme_detecte = nom_algo + score_probabilite = score + print(f"Algorithme détecté: {algorithme_detecte} (score: {score:.2f})") + break + + if not algorithme_detecte: + print("Aucun algorithme coréctement détecté ") + temps_execution = time.time() - debut_analyse + return ResultatAnalyse("", b"", 0.0, b"", temps_execution, nb_tentatives) + + temps_execution = time.time() - debut_analyse + + return ResultatAnalyse(algorithme_detecte, cle, score_probabilite, texte_dechiffre, temps_execution, nb_tentatives) + + except Exception as e: + print(f"Erreur lors de l'analyse: {str(e)}") + temps_execution = time.time() - debut_analyse + return ResultatAnalyse("", b"", 0.0, b"", temps_execution, 0) + + def mission_complete_automatique(self, dossier_chiffres: str) -> List[ResultatAnalyse]: + """ + MISSION COMPLÈTE AUTOMATIQUE + - Analyse des 5 fichiers séquentiellement + - Tentatives de déchiffrement avec retour visuel + - Rapport de synthèse final + + Args: + dossier_chiffres(str): dossier contenant les fichiers chiffrés + + Returns: + list[ResultatAnalyse]: liste des résultats d'analyse + """ + + debut_mission = time.time() + resultats = [] + + try: + # Récupération des fichiers .enc + fichiers_enc = [f for f in os.listdir(dossier_chiffres) if f.endswith(".enc")] + + if not fichiers_enc: + print("Aucun fichier .enc trouvé dans le dossier") + return [] + + print(f"{len(fichiers_enc)} fichiers .enc détectés") + print("\nANALYSE SÉQUENTIELLE DES FICHIERS") + + for i, fichier in enumerate(fichiers_enc, 1): + print(f"\nFICHIER {i}/{len(fichiers_enc)}: {fichier}") - if score_probabilite > 0.5: # Comparaison correcte avec le seuil - algorithme_detecte = nom_algo # Stockage du nom de l'algorithme - print(f"Algorithme détecté: {algorithme_detecte} (score: {score_probabilite:.2f})") + chemin_fichier = os.path.join(dossier_chiffres, fichier) + + # Analyse du fichier + resultat = self.analyser_fichier_specifique(chemin_fichier) + + # Tentative de déchiffrement si algorithme détecté + if resultat.algo: + print(f"\nTENTATIVE DE DÉCHIFFREMENT") - # Génération des clés candidates + analyzer = self.analyzers[resultat.algo] cles_candidates = analyzer.generer_cles_candidates("dicoEn") - print(f"{len(cles_candidates)} clés candidates générées") - # Test de déchiffrement avec la première clé (pour l'exemple) if cles_candidates: - texte_dechiffre = analyzer.dechiffrer(chemin_fichier_chiffre, cles_candidates[0]) - if texte_dechiffre: - cle = cles_candidates[0] - print("Déchiffrement réussi avec la première clé!") + print(f"Test de {len(cles_candidates)} clés candidates...") + + for j, cle in enumerate(cles_candidates): + resultat.nb_tentatives += 1 + + if j % 100 == 0: # retour visuel tous les 100 essais + print(f" Tentative {j+1}/{len(cles_candidates)}...") + + texte_dechiffre = analyzer.dechiffrer(chemin_fichier, cle) + if texte_dechiffre and len(texte_dechiffre) > 0: + resultat.cle = cle + resultat.texte_dechiffre = texte_dechiffre + print(f" Clé trouvée après {j+1} tentatives!") + break else: - print("Déchiffrement échoué avec la première clé") - break + print(" Aucune clé valide trouvée") + else: + print(" Aucune clé candidate générée") + + resultats.append(resultat) + + # retour visuel + if resultat.algo: + print(f"{fichier}: {resultat.algo} (score: {resultat.score_probabilite:.2f})") + else: + print(f"{fichier}: Aucun algorithme détecté") - if not algorithme_detecte: - print("Aucun algorithme détecté avec confiance suffisante") + # Rapport de synthèse final + self.generer_rapport_synthese(resultats, time.time() - debut_mission) - return ResultatAnalyse(algorithme_detecte, cle, texte_dechiffre) - except Exception as e: - print(f"Erreur lors de l'analyse du fichier {chemin_fichier_chiffre}: {str(e)}") - return ResultatAnalyse("", b"", b"") - - - def Analyser_fichiers_sequentiels(self, dossier_chiffres: str) -> list[ResultatAnalyse]: - """ - Analyse plusieurs fichiers chiffrés dans un dossier et retourne les résultats de l'analyse. + # Mise à jour des statistiques globales + self.missions_completees.append({ + "dossier": dossier_chiffres, + "resultats": resultats, + "temps_total": time.time() - debut_mission + }) - Args: - dossier_chiffres(str): dossier contenant les fichiers chiffrés à analyser + return resultats - Returns: - list[ResultatAnalyse]: liste des résultats d'analyse pour chaque fichier + except Exception as e: + print(f"Erreur lors de la mission complète: {str(e)}") + return [] + + def attaque_dictionnaire_manuelle(self, chemin_fichier: str, algorithme_choisi: str) -> ResultatAnalyse: + """ + ATTAQUE PAR DICTIONNAIRE MANUELLE + - Choix du fichier et de l'algorithme + - Suivi en temps réel des tentatives + - Affichage des résultats intermédiaires + + Args: + chemin_fichier(str): chemin du fichier à attaquer + algorithme_choisi(str): algorithme à utiliser + + Returns: + ResultatAnalyse: résultat de l'attaque """ + + + debut_attaque = time.time() + try: - resultats = [] - for fichier_chiffre in os.listdir(dossier_chiffres): - chemin_fichier_chiffre = os.path.join(dossier_chiffres, fichier_chiffre) - resultat = self.Analyser_fichier_uniquement(chemin_fichier_chiffre) - resultats.append(resultat) - return resultats + if algorithme_choisi not in self.analyzers: + print(f"Algorithme {algorithme_choisi} non disponible") + return ResultatAnalyse("", b"", 0.0, b"", 0.0, 0) + + analyzer = self.analyzers[algorithme_choisi] + + # Vérification de l'algorithme + score = analyzer.identifier_algo(chemin_fichier) + print(f"Score de confirmation: {score:.2f}") + + if score < 0.3: + print("Score de confiance faible pour cet algorithme") + + # Génération des clés candidates + print(f"Génération des clés candidates") + cles_candidates = analyzer.generer_cles_candidates("dicoEn") + print(f"{len(cles_candidates)} clés candidates générées") + + # Attaque par dictionnaire + + cle_trouvee = b"" + texte_dechiffre = b"" + nb_tentatives = 0 + + for i, cle in enumerate(cles_candidates): + nb_tentatives += 1 + + # retour visuel en temps réel + if i % 50 == 0: + print(f"Tentative {i+1}/{len(cles_candidates)}... ({(i+1)/len(cles_candidates)*100:.1f}%)") + texte_dechiffre = analyzer.dechiffrer(chemin_fichier, cle) + if texte_dechiffre and len(texte_dechiffre) > 0: + cle_trouvee = cle + break + else: + print(f"Aucune clé valide trouvée après {len(cles_candidates)} tentatives") + + temps_execution = time.time() - debut_attaque + print(f"Temps d'exécution: {temps_execution:.2f} secondes") + + return ResultatAnalyse(algorithme_choisi, cle_trouvee, score, texte_dechiffre, temps_execution, nb_tentatives) + except Exception as e: - print(f"Erreur lors de l'analyse des fichiers: {str(e)}") - return [] \ No newline at end of file + print(f"Erreur lors de l'attaque: {str(e)}") + temps_execution = time.time() - debut_attaque + return ResultatAnalyse("", b"", 0.0, b"", temps_execution, 0) + From b74715c5779696ed05345d7060984bfdd3baf78d Mon Sep 17 00:00:00 2001 From: wesley-kami Date: Tue, 5 Aug 2025 16:26:16 +0100 Subject: [PATCH 06/14] Ajout du guide d'utilisation --- guideUtilisation.txt | 15 ++++++++++ src/interface_console.py | 62 +++++++++++++++++++++++++++++++++++----- 2 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 guideUtilisation.txt diff --git a/guideUtilisation.txt b/guideUtilisation.txt new file mode 100644 index 0000000..e4451cd --- /dev/null +++ b/guideUtilisation.txt @@ -0,0 +1,15 @@ +## **Algorithmes déployés lors des mission** +**AES-256** : +###### 1. **Hello Word** : Ceci est un exemple veuillez suivre ce format pour la documentation de vos algorithmes + +**Chacha20** : +###### 1. **Hello Word** : Ceci est un exemple veuillez suivre ce format pour la documentation de vos algorithmes + +**Blowfish** : +###### 1. **Hello Word** : Ceci est un exemple veuillez suivre ce format pour la documentation de vos algorithmes + +**AES-GCM** : +###### 1. **Hello Word** : Ceci est un exemple veuillez suivre ce format pour la documentation de vos algorithmes + +**Fernet** : +###### 1. **Hello Word** : Ceci est un exemple veuillez suivre ce format pour la documentation de vos algorithmes diff --git a/src/interface_console.py b/src/interface_console.py index fee6eb5..205140b 100644 --- a/src/interface_console.py +++ b/src/interface_console.py @@ -2,7 +2,9 @@ from rich.traceback import install from rich.markdown import Markdown from rich import print +from rich.text import Text from rich.prompt import Prompt +from rich.table import Table # from detecteur_crypto import Analyser_fichier_uniquement # from detecteur_crypto import Analyser_fichier_sequentiels import time, os @@ -66,10 +68,6 @@ def default_menu(self): self.menu_5() elif choix == "6": self.menu_6() - - while choix > "6" or choix < "1": - self.console.print("Veuillez entrer un nombre entre 1 et 6") - choix = self.prompt.ask("Veuillez choisir une option ",choices=["1","2","3","4","5","6"]) except ValueError: self.console.print("Veuillez entrer un nombre entre 1 et 6") except Exception as e: @@ -127,8 +125,58 @@ def menu_4(self): def menu_5(self): self.console.clear() self.dynamiqueText("Système d'aide intégré","green") - time.sleep(0.04) - self.default_menu() + title = Markdown("# Guide d'utilisation",style="yellow bold") + contexte_title = Markdown("### 📋 Contexte de la Mission",style="green") + contexte= Markdown("### Vous êtes un analyste en cybersécurité travaillant pour une agence gouvernementale. Lors d'une opération d'investigation, votre équipe a intercepté 5 fichiers chiffrés contenant des informations cruciales. Votre mission est d'identifier l'algorithme de chiffrement utilisé pour chaque fichier, de découvrir la clé de déchiffrement, puis d'extraire le contenu secret.\n" \ + "### Les criminels ont utilisé 5 algorithmes de chiffrement symétrique différents pour protéger leurs communications. Votre expertise en cryptanalyse sera mise à l'épreuve pour déchiffrer ces messages et découvrir les secrets qu'ils contiennent.\n") + + mission_table = Table(title = "Missions Accomplies",style="",show_lines= True,leading=1) + mission_table.add_column("Intitulé",style="violet",justify="center") + mission_table.add_column("Fichier cible",style="red",justify="center") + mission_table.add_column('Indice',style="yellow",justify="center") + mission_table.add_column("Défi",style="green",justify="center") + + mission_table.add_row("AES-256-CBC","mission1.enc","La clé est liée à une ville française célèbre et une année olympique"," Identifier l'algorithme AES en mode CBC et récupérer la clé par attaque dictionnaire") + mission_table.add_row("ChaCha20","mission2.enc","Combinaison d'une année récente et d'un mot de passe anglais commun","Reconnaître le chiffrement de flux moderne ChaCha20") + mission_table.add_row("Blowfish","mission3.enc","Nom d'un algorithme de hachage populaire suivi de chiffres","Détecter l'algorithme Blowfish et ses spécificités") + mission_table.add_row("AES-256-GCM","mission4.enc","Acronyme d'une organisation internationale + année courante","Identifier le mode authentifié GCM et gérer l'authentification") + mission_table.add_row("Fernet","mission5.enc","Phrase française simple encodée, liée à notre domaine d'étude","Reconnaître le format Fernet et sa structure particulière") + + f = open("guideUtilisation.txt",'r') + algo_docs = Markdown(f.read()) + f.close() + + process= Markdown("### Processus d'usage logiciel",style="purple underline") + intro = Markdown("Comme vous l'avez probablement remarqué le menu de ce logiciel est composé de 06 options dont 04 principales :") + usage_guide_1 = Markdown("1. ### Analyse d'un fichier spécifique \n",style="black on white") + analysis_1 = Markdown(" Cette option a pour but de traiter un fichier crypter ( prise en charge des '.enc' exceptionnellement ) afin d'identifier l'algorithme \n\n" \ + " de cryptage qui lui a été appliqué ainsi que le score de probabilité de chaque algorithme de cryptage cité ci-dessus \n\n") + usage_guide_2 = Markdown("2. ### Mission complète automatique \n",style="black on white") + analysis_2 = Markdown(" Cette option permet de traiter les 05 missions de façon séquentielle afin de ressortir de chacune d'entre elle :\n\n" \ + " -la clé de crypatage\n\n" \ + " -le message déchiffrer\n\n" \ + " A la fin des traitement un synthèse finale est générée sur l'état des Test effectué") + + usage_guide_3 = Markdown("3. ### Attaque par dictionnaire manuelle",style="black on white") + analysis_3=Markdown(" En optant pour cette option vous aurez à sélectionner le fichier que vous souhaitez décrypté et par suite l'algorithme de décryptage que vous voudiez appliquer.\n" \ + " Vous aurez dun suivez en tempps réel de l'evolution des tentatives ainsi que l'affichage du résultat obtenu") + + usage_guide_4 = Markdown("4. ### Affichage des rapports \n",style="black on white") + analysis_4 =Markdown(" Cette option vous permettra d'oberver les rapports des différents tests de décryptages effectués au cours de l'utilisation de ce logiciel") + + final = Markdown("# 😁​ Merci d'utiliser notre logiciel 👾​ et bonne continuation ( **Appuyez sur la touche Enter pour retourner au menu principal** )",style="yellow") + + # print(title,contexte_title,contexte,mission_table,algo_docs,process,intro,usage_guide_1,analysis_1,usage_guide_2,analysis_2,usage_guide_3,analysis_3,usage_guide_4,analysis_4,final) + # escape = input('') + guides = [title,contexte_title,contexte,mission_table,algo_docs,process,intro,usage_guide_1,analysis_1,usage_guide_2,analysis_2,usage_guide_3,analysis_3,usage_guide_4,analysis_4,final] + + for guide in guides: + print(guide) + print("\n") + + escape= input('') + if escape != None: + self.default_menu() def menu_6(self): self.console.clear() @@ -136,4 +184,4 @@ def menu_6(self): time.sleep(2) self.console.clear() -consoleInterface() +consoleInterface() \ No newline at end of file From a45afa078bf4035637d4aad33aca92a19c7d08c7 Mon Sep 17 00:00:00 2001 From: wesley-kami Date: Thu, 7 Aug 2025 00:02:11 +0100 Subject: [PATCH 07/14] =?UTF-8?q?mission1=20+=20console=20pr=C3=A9mices?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/detecteur_crypto.py | 1 - src/interface_console.py | 13 ++++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/detecteur_crypto.py b/src/detecteur_crypto.py index 93fb35d..83aca26 100644 --- a/src/detecteur_crypto.py +++ b/src/detecteur_crypto.py @@ -249,4 +249,3 @@ def attaque_dictionnaire_manuelle(self, chemin_fichier: str, algorithme_choisi: print(f"Erreur lors de l'attaque: {str(e)}") temps_execution = time.time() - debut_attaque return ResultatAnalyse("", b"", 0.0, b"", temps_execution, 0) - diff --git a/src/interface_console.py b/src/interface_console.py index 205140b..4ace459 100644 --- a/src/interface_console.py +++ b/src/interface_console.py @@ -7,6 +7,7 @@ from rich.table import Table # from detecteur_crypto import Analyser_fichier_uniquement # from detecteur_crypto import Analyser_fichier_sequentiels +from detecteur_crypto import DetecteurCryptoOrchestrateur import time, os install() @@ -76,16 +77,18 @@ def default_menu(self): def menu_1(self): self.console.clear() self.dynamiqueText("Analyse d'un fichier spécifique","green") - self.dynamiqueText("Veuillez entrer le chemin du fichier :","white") + self.dynamiqueText("Veuillez entrer le chemin du fichier","yellow") + fichier = self.prompt.ask("") time.sleep(0.04) # chemin_fichier = self.prompt.ask("Veuillez entrer le chemin du fichier : ") # resultat = Analyser_fichier_uniquement(chemin_fichier) self.console.clear() - self.dynamiqueText("Analyse en cours...","green") - time.sleep(0.04) - self.console.clear() + # self.dynamiqueText("Analyse en cours...","green") + # time.sleep(0.04) + # self.console.clear() self.dynamiqueText("Analyse terminée","green") - time.sleep(0.04) + self.console.print(DetecteurCryptoOrchestrateur().analyser_fichier_specifique(fichier)) + # time.sleep(0.04) # def menu_2(self): From ced12b268746fb13305a81d53e216ccb31763b85 Mon Sep 17 00:00:00 2001 From: wesley-kami Date: Thu, 7 Aug 2025 14:05:41 +0100 Subject: [PATCH 08/14] test --- main.py | 2 ++ src/detecteur_crypto.py | 2 ++ src/interface_console.py | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index e69de29..e548258 100644 --- a/main.py +++ b/main.py @@ -0,0 +1,2 @@ +from src.detecteur_crypto import DetecteurCryptoOrchestrateur +print(DetecteurCryptoOrchestrateur().analyser_fichier_specifique('data/mission1.enc')) \ No newline at end of file diff --git a/src/detecteur_crypto.py b/src/detecteur_crypto.py index 83aca26..9a354a6 100644 --- a/src/detecteur_crypto.py +++ b/src/detecteur_crypto.py @@ -249,3 +249,5 @@ def attaque_dictionnaire_manuelle(self, chemin_fichier: str, algorithme_choisi: print(f"Erreur lors de l'attaque: {str(e)}") temps_execution = time.time() - debut_attaque return ResultatAnalyse("", b"", 0.0, b"", temps_execution, 0) + +# print(DetecteurCryptoOrchestrateur().analyser_fichier_specifique('data/mission1.enc')) \ No newline at end of file diff --git a/src/interface_console.py b/src/interface_console.py index 4ace459..f36306d 100644 --- a/src/interface_console.py +++ b/src/interface_console.py @@ -7,7 +7,7 @@ from rich.table import Table # from detecteur_crypto import Analyser_fichier_uniquement # from detecteur_crypto import Analyser_fichier_sequentiels -from detecteur_crypto import DetecteurCryptoOrchestrateur +from .detecteur_crypto import DetecteurCryptoOrchestrateur import time, os install() From d18e690b6b1c636cf4989ca6e287d9c47bcb6578 Mon Sep 17 00:00:00 2001 From: wesley-kami Date: Thu, 7 Aug 2025 23:18:56 +0100 Subject: [PATCH 09/14] =?UTF-8?q?finalisation=20de=20l'int=C3=A9gration=20?= =?UTF-8?q?mission1=20+=20console=20plus=20de=20stress?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/detecteur_crypto.py | 8 +++---- src/interface_console.py | 50 +++++++++++++++++++++++++++------------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/detecteur_crypto.py b/src/detecteur_crypto.py index 9a354a6..4384812 100644 --- a/src/detecteur_crypto.py +++ b/src/detecteur_crypto.py @@ -66,7 +66,7 @@ def analyser_fichier_specifique(self, chemin_fichier_chiffre: str) -> ResultatAn try: # Vérification de l'existence du fichier - if not os.path.exists(chemin_fichier_chiffre): + if not os.path.exists(f"data/{chemin_fichier_chiffre}"): print("Erreur: Fichier non trouvé") return ResultatAnalyse("", b"", 0.0, b"", 0.0, 0) @@ -80,14 +80,14 @@ def analyser_fichier_specifique(self, chemin_fichier_chiffre: str) -> ResultatAn # Parcours des algorithmes disponibles scores_algorithmes = {} for nom_algo, analyzer in self.analyzers.items(): - score = analyzer.identifier_algo(chemin_fichier_chiffre) + score = analyzer.identifier_algo(f"data/{chemin_fichier_chiffre}") scores_algorithmes[nom_algo] = score - print(f"{nom_algo}: score {score:.2f}") + # print(f"{nom_algo}: score {score:.2f}") if score > 0.5: # Seuil de confiance algorithme_detecte = nom_algo score_probabilite = score - print(f"Algorithme détecté: {algorithme_detecte} (score: {score:.2f})") + # print(f"Algorithme détecté: {algorithme_detecte} (score: {score:.2f})") break if not algorithme_detecte: diff --git a/src/interface_console.py b/src/interface_console.py index f36306d..2b54ce6 100644 --- a/src/interface_console.py +++ b/src/interface_console.py @@ -35,7 +35,7 @@ def dynamiqueText(self,text,color): for char in text: self.console.print(f"[{color}]{char}[/{color}]",end='') - time.sleep(0.04) + time.sleep(0.02) self.console.print('\n') @@ -44,7 +44,7 @@ def default_menu(self): self.console.clear() self.dynamiqueText("😈​ Bienvenue sur Forensic je suis Crypto votre assitant IA minimaliste 🤖​ ","green") self.dynamiqueText("En quoi puis-je vous aider ? :","white") - time.sleep(0.04) + time.sleep(0.02) menuTag = Markdown("# Menu",style="blue") menuOption = Markdown("1. #### Analyse d'un fichier spécifique \n" \ "2. #### Mission complète automatique \n" \ @@ -53,7 +53,7 @@ def default_menu(self): "5. #### Système d'aide intégré \n" \ "6. #### Quitter") self.console.print(menuTag,menuOption) - time.sleep(0.04) + time.sleep(0.02) choix = self.prompt.ask("Veuillez choisir une option ",choices=["1","2","3","4","5","6"]) try: @@ -79,51 +79,69 @@ def menu_1(self): self.dynamiqueText("Analyse d'un fichier spécifique","green") self.dynamiqueText("Veuillez entrer le chemin du fichier","yellow") fichier = self.prompt.ask("") - time.sleep(0.04) + time.sleep(0.02) # chemin_fichier = self.prompt.ask("Veuillez entrer le chemin du fichier : ") # resultat = Analyser_fichier_uniquement(chemin_fichier) - self.console.clear() + # self.console.clear() # self.dynamiqueText("Analyse en cours...","green") - # time.sleep(0.04) + # time.sleep(0.02) # self.console.clear() self.dynamiqueText("Analyse terminée","green") - self.console.print(DetecteurCryptoOrchestrateur().analyser_fichier_specifique(fichier)) - # time.sleep(0.04) + data = DetecteurCryptoOrchestrateur().analyser_fichier_specifique(fichier) + print(f"\n[bold]Algorithme détecté[/bold] : [yellow]{data.algo}[/yellow]") + # print(data.cle) + print(f"\n[bold]Score de probabilité[/bold] : [green]{data.score_probabilite}[/green]") + # print(data.texte_dechiffre) + print(f"\n[bold]Temps d'éxécution[/bold] : [green]{round(data.temps_execution,4)}[/green] s") + esc=input("Veuillez appuyer sur la touche entrer pour retrouner au menu principal") + if esc=="": + self.default_menu() + else : self.default_menu() + # print(data.nb_tentatives) + # time.sleep(0.02) # def menu_2(self): self.console.clear() self.dynamiqueText("Mission complète automatique","green") self.dynamiqueText("Veuillez entrer le chemin du dossier :","white") - time.sleep(0.04) + time.sleep(0.02) # chemin_dossier = self.prompt.ask("Veuillez entrer le chemin du dossier : ") self.console.clear() self.dynamiqueText("Mission en cours...","green") - time.sleep(0.04) + time.sleep(0.02) self.console.clear() self.dynamiqueText("Mission terminée","green") - time.sleep(0.04) + time.sleep(0.02) self.default_menu() def menu_3(self): self.console.clear() self.dynamiqueText("Attaque par dictionnaire manuelle","green") self.dynamiqueText("Veuillez entrer le chemin du fichier :","white") - time.sleep(0.04) + time.sleep(0.02) # chemin_fichier = self.prompt.ask("Veuillez entrer le chemin du fichier : ") self.console.clear() self.dynamiqueText("Attaque en cours...","green") - time.sleep(0.04) + time.sleep(0.02) self.console.clear() self.dynamiqueText("Attaque terminée","green") - time.sleep(0.04) + time.sleep(0.02) self.default_menu() def menu_4(self): self.console.clear() self.dynamiqueText("Affichage des rapports","green") - time.sleep(0.04) - self.default_menu() + time.sleep(0.02) + f = open("rapport_mission.txt",'r') + rapports = f.read() + for rapport in rapports: + print(f"\n{rapport}") + f.close() + esc = input('Veuillez appuyez sur la touche entrer pour continuer') + if esc=='': + self.default_menu() + else: self.default_menu() def menu_5(self): self.console.clear() From 880d922534e695ba1342ec5c9b296b6891d8cda9 Mon Sep 17 00:00:00 2001 From: e-mandy Date: Fri, 8 Aug 2025 21:32:51 +0100 Subject: [PATCH 10/14] =?UTF-8?q?Int=C3=A9gration=20de=20l'AesGcmAnalyzer?= =?UTF-8?q?=20dans=20l'orchestrateur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/detecteur_crypto.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/detecteur_crypto.py b/src/detecteur_crypto.py index cab72aa..3dd1f5a 100644 --- a/src/detecteur_crypto.py +++ b/src/detecteur_crypto.py @@ -8,6 +8,7 @@ from crypto_analyzer import CryptoAnalyzer from analyzers.chacha20_analyzer import ChaCha20_Analyzer from analyzers.blowfish_analyzer import Blowfish_Analyzer +from analyzers.aes_gcm_analyzer import Aes_Gcm_Analyzer # Import des modules utilitaries from utils import est_dechiffre @@ -39,7 +40,8 @@ def __init__(self): self.analyzers: dict[str, CryptoAnalyzer] = { "AES-CBC": Aes_Cbc_Analyzer(), "ChaCha20": ChaCha20_Analyzer(), - "Blowfish": Blowfish_Analyzer() + "Blowfish": Blowfish_Analyzer(), + "AES-GCM": Aes_Gcm_Analyzer() } self.missions_completees: list[dict[str, Union[str, list[ResultatAnalyse], float]]] = [] self.statistiques_globales: dict[str, Union[int, float]] = { From d66b6a3d887336ec523df81f22b8c974c7cc9330 Mon Sep 17 00:00:00 2001 From: wesley-kami Date: Tue, 12 Aug 2025 11:07:47 +0100 Subject: [PATCH 11/14] =?UTF-8?q?impl=C3=A9mentation=20de=20l'attaque=20pa?= =?UTF-8?q?r=20dictionnaire?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/detecteur_crypto.py | 44 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/detecteur_crypto.py b/src/detecteur_crypto.py index 870d6a5..351ca71 100644 --- a/src/detecteur_crypto.py +++ b/src/detecteur_crypto.py @@ -3,6 +3,7 @@ import time from typing import List, Union from pathlib import Path +from rich.progress import Progress # Import des modules d'analyse from src.analyzers.aes_cbc_analyzer import Aes_Cbc_Analyzer from src.crypto_analyzer import CryptoAnalyzer @@ -358,6 +359,47 @@ def attaque_dictionnaire_manuelle(self, chemin_fichier: str, algorithme_choisi: print(f"Erreur lors de l'attaque: {str(e)}") temps_execution = time.time() - debut_attaque return ResultatAnalyse("", b"", 0.0, b"", temps_execution, 0) + + def attaque_dictionnaire(self,chemin_fichier_chiffrer: str, algo : str, chemin_dico : str = "keys/wordlist.txt"): + + with Progress() as progress: + analyzer = self.analyzers[algo] + + cle_candidates = analyzer.generer_cles_candidates(chemin_dico) + + with open(chemin_dico,'r') as d: + dico = d.readlines() + + with open(f"data/{chemin_fichier_chiffrer}",'rb') as f : + texte_chiffrer = f.read() + + task_id = progress.add_task("Testing...",total=len(cle_candidates)) + + current_task = 0 + + advance = 1 + + + while current_task < len(cle_candidates) : + time.sleep(0.5) + + essai_dechiffrage = analyzer.dechiffrer(f"data/{chemin_fichier_chiffrer}", cle_candidates[current_task]) + + if essai_dechiffrage != b"" : + + progress.update(task_id,advance=len(cle_candidates) - current_task) + + return essai_dechiffrage + + current_task+=1 + + progress.update(task_id,advance=advance) + + + return "Aucune clé trouvé" + + # print("\n Process is done ...") + -# print(DetecteurCryptoOrchestrateur().analyser_fichier_specifique(f"{os.path.abspath(os.curdir)}\\CryptoForensic-Python\\data\\mission2.enc")) +# print(DetecteurCryptoOrchestrateur().attaque_dictionnaire("mission1.enc","Fernet")) From 6e95375d3682c54e743ec9fab08ea77b913482b4 Mon Sep 17 00:00:00 2001 From: mouwaficbdr Date: Tue, 12 Aug 2025 14:19:55 +0100 Subject: [PATCH 12/14] fix: Correction de l'affichage du texte dechiffre dans l'orchestrateur --- src/detecteur_crypto.py | 813 ++++++++++++++++++++-------------------- 1 file changed, 408 insertions(+), 405 deletions(-) diff --git a/src/detecteur_crypto.py b/src/detecteur_crypto.py index 351ca71..4ce07e1 100644 --- a/src/detecteur_crypto.py +++ b/src/detecteur_crypto.py @@ -1,405 +1,408 @@ -# Import des modules -import os -import time -from typing import List, Union -from pathlib import Path -from rich.progress import Progress -# Import des modules d'analyse -from src.analyzers.aes_cbc_analyzer import Aes_Cbc_Analyzer -from src.crypto_analyzer import CryptoAnalyzer -from src.analyzers.chacha20_analyzer import ChaCha20_Analyzer -from src.analyzers.blowfish_analyzer import Blowfish_Analyzer -from src.analyzers.aes_gcm_analyzer import Aes_Gcm_Analyzer -from src.analyzers.fernet_analyzer import FernetAnalyzer -from src.rapport_mission import rapport_mission -# Import des modules utilitaries -from src.utils import verifier_texte_dechiffre -from rich.progress import Progress -from rich.markdown import Markdown -from rich.console import Console -class ResultatAnalyse: - """ - Classe représentant un résultat d'analyse. - """ - 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): - self.algo = algo - self.cle = cle - self.score_probabilite = score_probabilite - self.texte_dechiffre = texte_dechiffre - self.temps_execution = temps_execution - self.nb_tentatives = nb_tentatives - self.fichier = fichier, - self.taux_succes = taux_succes -class DetecteurCryptoOrchestrateur: - """ - Classe principale qui centralise tout: - -Lance l'analyse des fichiers et identifie l'algorithme probable, - -Lance les attaques par dictionnaire, - -Lance et coordonnes le processus de dechiffrement - """ - - _NBR_OPERATION_MISSION = 4 - _NBR_OPERATION_ANALYSE = 3 - - def __init__(self): - """ - Initialisation de tous les modules d'analyse disponibles - """ - self.analyzers: dict[str, CryptoAnalyzer] = { - "AES-CBC-256": Aes_Cbc_Analyzer(), - "ChaCha20": ChaCha20_Analyzer(), - "Blowfish": Blowfish_Analyzer(), - "AES-GCM": Aes_Gcm_Analyzer(), - "Fernet": FernetAnalyzer(), - } - self.missions_completees: list[dict[str, Union[str, list[ResultatAnalyse], float]]] = [] - self.statistiques_globales: dict[str, Union[int, float]] = { - "total_fichiers": 0, - "fichiers_dechiffres": 0, - "temps_total": 0.0, - "tentatives_total": 0 - } - - def analyser_fichier_specifique(self, chemin_fichier_chiffre: str, progress : Progress, task, error:bool, nbr_opr_mission: int) -> ResultatAnalyse: - """ - ANALYSE D'UN FICHIER SPÉCIFIQUE - - Sélection du fichier à analyser - - Identification automatique de l'algorithme - - Affichage des scores de probabilité - - Args: - chemin_fichier_chiffre(str): chemin du fichier chiffré à analyser - progress (Progress) : la progress bar à mettre à jour - error(bool): nécessaire pour déterminer les erreurs et définir le message de final de la progress bar - Returns: - ResultatAnalyse: résultat de l'analyse - """ - debut_analyse = time.time() - - try: - # Vérification de l'existence du fichier - avance = (100/(self._NBR_OPERATION_ANALYSE * nbr_opr_mission)) - time.sleep(0.3) # Done : Intégrer la progress bar -> step : Verification du chemin de fichier fourni - progress.update(task_id=task, description="Verification du chemin de fichier fourni", advance=avance * 0.3) - time.sleep(1) - - if not os.path.isfile(Path('data')/f"{chemin_fichier_chiffre}"): - time.sleep(0.3) # TODO : Intégrer la progress bar -> step : Verification du chemin de fichier fourni - progress.update(task_id=task, description="Fichier non trouvé ❌ (Aborting...)", advance=((avance * self._NBR_OPERATION_ANALYSE) - avance * 0.3) ) - time.sleep(1) - error = True - return ResultatAnalyse("", b"", 0.0, b"", 0.0, 0) - - # Initialisation des variables - time.sleep(0.5) # TODO : Mise à jour de la progress bar -> step : Initialisation des utilitaires pour l'identification - progress.update(task_id=task, description="Initialisation des utilitaires pour l'identification", advance=avance*0.2) - time.sleep(1) - - algorithme_detecte = "" - cle = b"" - score_probabilite = 0.0 - texte_dechiffre = b"" - nb_tentatives = 0 - - # Parcours des algorithmes disponibles - scores_algorithmes = {} - - # Pour les arrêts en cas d'erreurs, servira à upgrade la progress bar - cumul_progress_avance = 0 - - for nom_algo, analyzer in self.analyzers.items(): - avance_algo = avance/(len(self.analyzers)*3 * 0.5) - time.sleep(0.5) # TODO : Mise à jour de la progress bar -> step : Utilisation de {algrorithme} pour déterminer le chiffrement - progress.update(task_id=task, description=f"Utilisation de {nom_algo} pour déterminer le chiffrement", advance=avance_algo) - time.sleep(1) - - score = analyzer.identifier_algo(f"data/{chemin_fichier_chiffre}") - scores_algorithmes[nom_algo] = score - - time.sleep(0.5) # TODO : Mise à jour de la progress bar -> step : Analyse des résultats d'identification - progress.update(task_id=task, description="Analyse des résultats d'identification", advance=avance_algo) - time.sleep(1) - - cumul_progress_avance += 2 * avance_algo - - if score > 0.9 : # Seuil de confiance - time.sleep(1) # TODO : Mise à jour de la progress bar -> step : Détection réussie pour {algorithme} et préparation du rapport d'analyse - progress.update(task_id=task, description=f"Détection réussie pour {nom_algo} et préparation du rapport d'analyse", advance=((100/nbr_opr_mission) - cumul_progress_avance)) - time.sleep(1) - - algorithme_detecte = nom_algo - score_probabilite = score - break - else : - time.sleep(1) # TODO : Intégrer la progress bar -> step : Echec d'identification pour {algorithme} - progress.update(task_id=task, description=f"Echec d'identification pour {nom_algo}", advance=avance_algo) - time.sleep(1) - cumul_progress_avance += avance_algo - - if not algorithme_detecte: - print("Aucun algorithme correctement détecté ") - temps_execution = time.time() - debut_analyse - return ResultatAnalyse("", b"", 0.0, b"", temps_execution, nb_tentatives, chemin_fichier_chiffre, 0) - - temps_execution = time.time() - debut_analyse - - return ResultatAnalyse(algorithme_detecte, cle, score_probabilite, texte_dechiffre, temps_execution, nb_tentatives, chemin_fichier_chiffre, 0) - - except Exception as e: - print(f"Erreur lors de l'analyse: {str(e)}") - temps_execution = time.time() - debut_analyse - error = True - return ResultatAnalyse("", b"", 0.0, b"", temps_execution, 0, chemin_fichier_chiffre) - - def __tenter_dechiffrement_avec_dictionnaire(self, chemin_fichier: str, cles_candidates: list[bytes], analyzer: CryptoAnalyzer, resultat: ResultatAnalyse): - """ - Tente de déchiffrer un fichier avec les clés candidates et l'analyzer correspondant - - Args: - chemin_fichier(str) : chemin vers le fichier - cles_candidates(list[bytes]) : les clés candidates retenus par le dossier de clés sur la base des indices - analyzer(CryptoAnalyzer) : l'Analyzer correspondant à ce fichier - resultat(ResultatAnalyse) : les résultats de l'analyse de fichier - - Returns : - bool : si une erreur est survenue ou non - """ - for j, cle in enumerate(cles_candidates): - resultat.nb_tentatives += 1 - - texte_dechiffre = analyzer.dechiffrer(chemin_fichier, cle).decode('utf-8') - succes = verifier_texte_dechiffre(texte_dechiffre)['taux_succes'] - - if texte_dechiffre and succes > 60 and len(texte_dechiffre) > 0: - resultat.cle = cle - resultat.texte_dechiffre = texte_dechiffre - resultat.taux_succes = succes - print(f"Clé trouvée après {j+1} tentatives!") - return False - - print("Aucune clé valide trouvée") - return True - - def mission_complete_automatique(self, dossier_chiffres: str, chemin_dictionnaire: str) -> List[ResultatAnalyse]: - """ - MISSION COMPLÈTE AUTOMATIQUE - - Analyse des 5 fichiers séquentiellement - - Tentatives de déchiffrement avec retour visuel - - Rapport de synthèse final - - Args: - dossier_chiffres(str): dossier contenant les fichiers chiffrés - - Returns: - list[ResultatAnalyse]: liste des résultats d'analyse - """ - - debut_mission = time.time() - resultats: list[ResultatAnalyse] = [] - try: - with Progress() as progress : - # Récupération des fichiers .enc - fichiers_enc = [f for f in os.listdir(dossier_chiffres) if f.endswith(".enc")] - - if not fichiers_enc: - print("Aucun fichier .enc trouvé dans le dossier") - return [] - - print(f"{len(fichiers_enc)} fichiers .enc détectés") - print("\nANALYSE SÉQUENTIELLE DES FICHIERS") - time.sleep(0.5) - for i, fichier in enumerate(fichiers_enc, 0): - print(f"\nFICHIER {i+1}/{len(fichiers_enc)}: {fichier}") - - # TODO: New progress bar -> step: Analyse du fichier mission{i+1}.enc - task = progress.add_task(f"Analyse du fichier mission{i+1}.enc...", total=100) - time.sleep(0.5) - - chemin_fichier = os.path.join(dossier_chiffres, fichier) - - # Analyse du fichier - error = False - resultat = self.analyser_fichier_specifique(fichier, progress, task, error, self._NBR_OPERATION_MISSION) - - # Tentative de déchiffrement si algorithme détecté - if resultat.algo: - # TODO: MAJ de la progress bar -> step: Amorçage de la phase de déchiffrement - progress.update(task, description="Amorçage de la phase de déchiffrement...", advance=((100/self._NBR_OPERATION_MISSION) * 0.5)) - time.sleep(1) - - analyzer = self.analyzers[resultat.algo] - - # TODO: MAJ de la progress bar -> step: Récupération des clés candidates - progress.update(task, description="Récupération des clés candidates", advance=(100/self._NBR_OPERATION_MISSION)*0.5) - time.sleep(1) - - cles_candidates = analyzer.generer_cles_candidates(chemin_dictionnaire) - - if cles_candidates: - print(f"Test de {len(cles_candidates)} clés candidates...") - # TODO: MAJ de la progress bar -> step: Test de déchiffrement - progress.update(task, description="Test de déchiffrement", advance=(100/self._NBR_OPERATION_MISSION)) - time.sleep(3) - - error = self.__tenter_dechiffrement_avec_dictionnaire(chemin_fichier, cles_candidates, analyzer, resultat) - - else: - # TODO: MAJ de la progress bar -> step: Abort et récupération des résultats d'analyse - progress.update(task, description="Aucune clé candidate générée ❌ (Aborting ...)", advance=(100/self._NBR_OPERATION_MISSION)) - time.sleep(3) - error = True - - - resultats.append(resultat) - - # retour visuel - if resultat.algo: - # TODO: MAJ de la progress bar -> step: Finalsation et retour de résultats - progress.update(task, description="Finalisation et retour des résultats", advance=(100/self._NBR_OPERATION_MISSION)) - time.sleep(3) - - print(f"{fichier}: {resultat.algo} (score: {resultat.score_probabilite:.2f})") - - message = "[bold green] Mission terminée. ✅[/bold green]\n\n" if not error else "[bold red] Mission terminée: Déchiffrement non concluant. ❌ [/bold red]\n\n" - Console().print(message) - else: - progress.update(task, description="Aborting et récupération des résultats d'analyse...", advance=100) - time.sleep(0.5) # TODO: MAJ de la progress bar -> step: Abort et récupération des résultats d'analyse - Console().print(f"[bold yellow] Mission terminée: Aucun algorithme détecté. ⚠️[/bold yellow]\n\n") - - progress.remove_task(task) - - # Rapport de synthèse final - with Progress() as progress : - task = progress.add_task("Préparation des rapports", total=100) # TODO: New progress bar -> step: Préparation des rapports (1 to 100%) - - while not progress.finished : - progress.update(task, description="Préparation des rapports", advance=2) - time.sleep(0.2) - for i in range(len(fichiers_enc)) : - resultat = { - 'algorithme': resultats[i].algo, - 'fichier': resultats[i].fichier, - 'cle': resultats[i].cle, - 'tentatives': resultats[i].nb_tentatives, - 'temps_execution': resultats[i].temps_execution, - 'taux_succes': resultats[i].taux_succes, - 'statut_succes' : 'Succès' if resultats[i].taux_succes > 60 else 'Echec', - 'texte_dechiffre' : resultats[i].texte_dechiffre - } - rapport_mission().generer_rapport_synthese(resultat) - progress.update(task, description="Mission complète effectuée.") # TODO: MAJ de la progress bar -> step: Mission complète effectuée - - # Mise à jour des statistiques globales - self.missions_completees.append({ - "dossier": dossier_chiffres, - "resultats": resultats, - "temps_total": time.time() - debut_mission - }) - - return resultats - - except Exception as e: - print(f"Erreur lors de la mission complète: {str(e)}") - return [] - - - def attaque_dictionnaire_manuelle(self, chemin_fichier: str, algorithme_choisi: str, chemin_dictionnaire: str) -> ResultatAnalyse: - """ - ATTAQUE PAR DICTIONNAIRE MANUELLE - - Choix du fichier et de l'algorithme - - Suivi en temps réel des tentatives - - Affichage des résultats intermédiaires - - Args: - chemin_fichier(str): chemin du fichier à attaquer - algorithme_choisi(str): algorithme à utiliser - - Returns: - ResultatAnalyse: résultat de l'attaque - """ - - - debut_attaque = time.time() - resultat = ResultatAnalyse("", b"", 0.0, b"", 0.0, 0) - - try: - if algorithme_choisi not in self.analyzers: - print(f"Algorithme {algorithme_choisi} non disponible") - return resultat - - analyzer = self.analyzers[algorithme_choisi] - - # Vérification de l'algorithme - score = analyzer.identifier_algo(chemin_fichier) - resultat.score_probabilite = score - resultat.algo = algorithme_choisi - print(f"Score de confirmation: {score:.2f}") - - if score < 0.3: - print("Score de confiance faible pour cet algorithme") - - # Génération des clés candidates - print(f"Génération des clés candidates") - cles_candidates = analyzer.generer_cles_candidates(chemin_dictionnaire) - print(f"{len(cles_candidates)} clés candidates générées") - - # Attaque par dictionnaire - - self.__tenter_dechiffrement_avec_dictionnaire(chemin_fichier, cles_candidates, analyzer, resultat) - - - temps_execution = time.time() - debut_attaque - resultat.temps_execution = temps_execution - print(f"Temps d'exécution: {temps_execution:.2f} secondes") - - return resultat - - except Exception as e: - print(f"Erreur lors de l'attaque: {str(e)}") - temps_execution = time.time() - debut_attaque - return ResultatAnalyse("", b"", 0.0, b"", temps_execution, 0) - - def attaque_dictionnaire(self,chemin_fichier_chiffrer: str, algo : str, chemin_dico : str = "keys/wordlist.txt"): - - with Progress() as progress: - analyzer = self.analyzers[algo] - - cle_candidates = analyzer.generer_cles_candidates(chemin_dico) - - with open(chemin_dico,'r') as d: - dico = d.readlines() - - with open(f"data/{chemin_fichier_chiffrer}",'rb') as f : - texte_chiffrer = f.read() - - task_id = progress.add_task("Testing...",total=len(cle_candidates)) - - current_task = 0 - - advance = 1 - - - while current_task < len(cle_candidates) : - time.sleep(0.5) - - essai_dechiffrage = analyzer.dechiffrer(f"data/{chemin_fichier_chiffrer}", cle_candidates[current_task]) - - if essai_dechiffrage != b"" : - - progress.update(task_id,advance=len(cle_candidates) - current_task) - - return essai_dechiffrage - - current_task+=1 - - progress.update(task_id,advance=advance) - - - return "Aucune clé trouvé" - - # print("\n Process is done ...") - - -# print(DetecteurCryptoOrchestrateur().attaque_dictionnaire("mission1.enc","Fernet")) - +# Import des modules +import os +import time +from typing import List, Union +from pathlib import Path +from rich.progress import Progress +# Import des modules d'analyse +from src.analyzers.aes_cbc_analyzer import Aes_Cbc_Analyzer +from src.crypto_analyzer import CryptoAnalyzer +from src.analyzers.chacha20_analyzer import ChaCha20_Analyzer +from src.analyzers.blowfish_analyzer import Blowfish_Analyzer +from src.analyzers.aes_gcm_analyzer import Aes_Gcm_Analyzer +from src.analyzers.fernet_analyzer import FernetAnalyzer +from src.rapport_mission import rapport_mission +# Import des modules utilitaries +from src.utils import verifier_texte_dechiffre +from rich.progress import Progress +from rich.markdown import Markdown +from rich.console import Console +class ResultatAnalyse: + """ + Classe représentant un résultat d'analyse. + """ + 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): + self.algo = algo + self.cle = cle + self.score_probabilite = score_probabilite + self.texte_dechiffre = texte_dechiffre + self.temps_execution = temps_execution + self.nb_tentatives = nb_tentatives + self.fichier = fichier, + self.taux_succes = taux_succes +class DetecteurCryptoOrchestrateur: + """ + Classe principale qui centralise tout: + -Lance l'analyse des fichiers et identifie l'algorithme probable, + -Lance les attaques par dictionnaire, + -Lance et coordonnes le processus de dechiffrement + """ + + _NBR_OPERATION_MISSION = 4 + _NBR_OPERATION_ANALYSE = 3 + + def __init__(self): + """ + Initialisation de tous les modules d'analyse disponibles + """ + self.analyzers: dict[str, CryptoAnalyzer] = { + "AES-CBC-256": Aes_Cbc_Analyzer(), + "ChaCha20": ChaCha20_Analyzer(), + "Blowfish": Blowfish_Analyzer(), + "AES-GCM": Aes_Gcm_Analyzer(), + "Fernet": FernetAnalyzer(), + } + self.missions_completees: list[dict[str, Union[str, list[ResultatAnalyse], float]]] = [] + self.statistiques_globales: dict[str, Union[int, float]] = { + "total_fichiers": 0, + "fichiers_dechiffres": 0, + "temps_total": 0.0, + "tentatives_total": 0 + } + + def analyser_fichier_specifique(self, chemin_fichier_chiffre: str, progress : Progress, task, error:bool, nbr_opr_mission: int) -> ResultatAnalyse: + """ + ANALYSE D'UN FICHIER SPÉCIFIQUE + - Sélection du fichier à analyser + - Identification automatique de l'algorithme + - Affichage des scores de probabilité + + Args: + chemin_fichier_chiffre(str): chemin du fichier chiffré à analyser + progress (Progress) : la progress bar à mettre à jour + error(bool): nécessaire pour déterminer les erreurs et définir le message de final de la progress bar + Returns: + ResultatAnalyse: résultat de l'analyse + """ + debut_analyse = time.time() + + try: + # Vérification de l'existence du fichier + avance = (100/(self._NBR_OPERATION_ANALYSE * nbr_opr_mission)) + time.sleep(0.3) # Done : Intégrer la progress bar -> step : Verification du chemin de fichier fourni + progress.update(task_id=task, description="Verification du chemin de fichier fourni", advance=avance * 0.3) + time.sleep(1) + + if not os.path.isfile(Path('data')/f"{chemin_fichier_chiffre}"): + time.sleep(0.3) # TODO : Intégrer la progress bar -> step : Verification du chemin de fichier fourni + progress.update(task_id=task, description="Fichier non trouvé ❌ (Aborting...)", advance=((avance * self._NBR_OPERATION_ANALYSE) - avance * 0.3) ) + time.sleep(1) + error = True + return ResultatAnalyse("", b"", 0.0, b"", 0.0, 0) + + # Initialisation des variables + time.sleep(0.5) # TODO : Mise à jour de la progress bar -> step : Initialisation des utilitaires pour l'identification + progress.update(task_id=task, description="Initialisation des utilitaires pour l'identification", advance=avance*0.2) + time.sleep(1) + + algorithme_detecte = "" + cle = b"" + score_probabilite = 0.0 + texte_dechiffre = b"" + nb_tentatives = 0 + + # Parcours des algorithmes disponibles + scores_algorithmes = {} + + # Pour les arrêts en cas d'erreurs, servira à upgrade la progress bar + cumul_progress_avance = 0 + + for nom_algo, analyzer in self.analyzers.items(): + avance_algo = avance/(len(self.analyzers)*3 * 0.5) + time.sleep(0.5) # TODO : Mise à jour de la progress bar -> step : Utilisation de {algrorithme} pour déterminer le chiffrement + progress.update(task_id=task, description=f"Utilisation de {nom_algo} pour déterminer le chiffrement", advance=avance_algo) + time.sleep(1) + + score = analyzer.identifier_algo(f"data/{chemin_fichier_chiffre}") + scores_algorithmes[nom_algo] = score + + time.sleep(0.5) # TODO : Mise à jour de la progress bar -> step : Analyse des résultats d'identification + progress.update(task_id=task, description="Analyse des résultats d'identification", advance=avance_algo) + time.sleep(1) + + cumul_progress_avance += 2 * avance_algo + + if score > 0.9 : # Seuil de confiance + time.sleep(1) # TODO : Mise à jour de la progress bar -> step : Détection réussie pour {algorithme} et préparation du rapport d'analyse + progress.update(task_id=task, description=f"Détection réussie pour {nom_algo} et préparation du rapport d'analyse", advance=((100/nbr_opr_mission) - cumul_progress_avance)) + time.sleep(1) + + algorithme_detecte = nom_algo + score_probabilite = score + break + else : + time.sleep(1) # TODO : Intégrer la progress bar -> step : Echec d'identification pour {algorithme} + progress.update(task_id=task, description=f"Echec d'identification pour {nom_algo}", advance=avance_algo) + time.sleep(1) + cumul_progress_avance += avance_algo + + if not algorithme_detecte: + print("Aucun algorithme correctement détecté ") + temps_execution = time.time() - debut_analyse + return ResultatAnalyse("", b"", 0.0, b"", temps_execution, nb_tentatives, chemin_fichier_chiffre, 0) + + temps_execution = time.time() - debut_analyse + + return ResultatAnalyse(algorithme_detecte, cle, score_probabilite, texte_dechiffre, temps_execution, nb_tentatives, chemin_fichier_chiffre, 0) + + except Exception as e: + print(f"Erreur lors de l'analyse: {str(e)}") + temps_execution = time.time() - debut_analyse + error = True + return ResultatAnalyse("", b"", 0.0, b"", temps_execution, 0, chemin_fichier_chiffre) + + def __tenter_dechiffrement_avec_dictionnaire(self, chemin_fichier: str, cles_candidates: list[bytes], analyzer: CryptoAnalyzer, resultat: ResultatAnalyse): + """ + Tente de déchiffrer un fichier avec les clés candidates et l'analyzer correspondant + + Args: + chemin_fichier(str) : chemin vers le fichier + cles_candidates(list[bytes]) : les clés candidates retenus par le dossier de clés sur la base des indices + analyzer(CryptoAnalyzer) : l'Analyzer correspondant à ce fichier + resultat(ResultatAnalyse) : les résultats de l'analyse de fichier + + Returns : + bool : si une erreur est survenue ou non + """ + for j, cle in enumerate(cles_candidates): + resultat.nb_tentatives += 1 + + # Déchiffrement et normalisation de l'affichage (évite les \x.. et caractères non imprimables) + donnees = analyzer.dechiffrer(chemin_fichier, cle) + texte_dechiffre = donnees.decode('utf-8', errors='ignore').replace('\x00', ' ') + succes = verifier_texte_dechiffre(texte_dechiffre)['taux_succes'] + + if texte_dechiffre and succes > 60 and len(texte_dechiffre) > 0: + resultat.cle = cle + resultat.texte_dechiffre = texte_dechiffre + resultat.taux_succes = succes + print(f"Clé trouvée après {j+1} tentatives!") + return False + + print("Aucune clé valide trouvée") + return True + + def mission_complete_automatique(self, dossier_chiffres: str, chemin_dictionnaire: str) -> List[ResultatAnalyse]: + """ + MISSION COMPLÈTE AUTOMATIQUE + - Analyse des 5 fichiers séquentiellement + - Tentatives de déchiffrement avec retour visuel + - Rapport de synthèse final + + Args: + dossier_chiffres(str): dossier contenant les fichiers chiffrés + + Returns: + list[ResultatAnalyse]: liste des résultats d'analyse + """ + + debut_mission = time.time() + resultats: list[ResultatAnalyse] = [] + try: + with Progress() as progress : + # Récupération des fichiers .enc + fichiers_enc = [f for f in os.listdir(dossier_chiffres) if f.endswith(".enc")] + + if not fichiers_enc: + print("Aucun fichier .enc trouvé dans le dossier") + return [] + + print(f"{len(fichiers_enc)} fichiers .enc détectés") + print("\nANALYSE SÉQUENTIELLE DES FICHIERS") + time.sleep(0.5) + for i, fichier in enumerate(fichiers_enc, 0): + print(f"\nFICHIER {i+1}/{len(fichiers_enc)}: {fichier}") + + # TODO: New progress bar -> step: Analyse du fichier mission{i+1}.enc + task = progress.add_task(f"Analyse du fichier mission{i+1}.enc...", total=100) + time.sleep(0.5) + + chemin_fichier = os.path.join(dossier_chiffres, fichier) + + # Analyse du fichier + error = False + resultat = self.analyser_fichier_specifique(fichier, progress, task, error, self._NBR_OPERATION_MISSION) + + # Tentative de déchiffrement si algorithme détecté + if resultat.algo: + # TODO: MAJ de la progress bar -> step: Amorçage de la phase de déchiffrement + progress.update(task, description="Amorçage de la phase de déchiffrement...", advance=((100/self._NBR_OPERATION_MISSION) * 0.5)) + time.sleep(1) + + analyzer = self.analyzers[resultat.algo] + + # TODO: MAJ de la progress bar -> step: Récupération des clés candidates + progress.update(task, description="Récupération des clés candidates", advance=(100/self._NBR_OPERATION_MISSION)*0.5) + time.sleep(1) + + cles_candidates = analyzer.generer_cles_candidates(chemin_dictionnaire) + + if cles_candidates: + print(f"Test de {len(cles_candidates)} clés candidates...") + # TODO: MAJ de la progress bar -> step: Test de déchiffrement + progress.update(task, description="Test de déchiffrement", advance=(100/self._NBR_OPERATION_MISSION)) + time.sleep(3) + + error = self.__tenter_dechiffrement_avec_dictionnaire(chemin_fichier, cles_candidates, analyzer, resultat) + + else: + # TODO: MAJ de la progress bar -> step: Abort et récupération des résultats d'analyse + progress.update(task, description="Aucune clé candidate générée ❌ (Aborting ...)", advance=(100/self._NBR_OPERATION_MISSION)) + time.sleep(3) + error = True + + + resultats.append(resultat) + + # retour visuel + if resultat.algo: + # TODO: MAJ de la progress bar -> step: Finalsation et retour de résultats + progress.update(task, description="Finalisation et retour des résultats", advance=(100/self._NBR_OPERATION_MISSION)) + time.sleep(3) + + print(f"{fichier}: {resultat.algo} (score: {resultat.score_probabilite:.2f})") + + message = "[bold green] Mission terminée. ✅[/bold green]\n\n" if not error else "[bold red] Mission terminée: Déchiffrement non concluant. ❌ [/bold red]\n\n" + Console().print(message) + else: + progress.update(task, description="Aborting et récupération des résultats d'analyse...", advance=100) + time.sleep(0.5) # TODO: MAJ de la progress bar -> step: Abort et récupération des résultats d'analyse + Console().print(f"[bold yellow] Mission terminée: Aucun algorithme détecté. ⚠️[/bold yellow]\n\n") + + progress.remove_task(task) + + # Rapport de synthèse final + with Progress() as progress : + task = progress.add_task("Préparation des rapports", total=100) # TODO: New progress bar -> step: Préparation des rapports (1 to 100%) + + while not progress.finished : + progress.update(task, description="Préparation des rapports", advance=2) + time.sleep(0.2) + for i in range(len(fichiers_enc)) : + resultat = { + 'algorithme': resultats[i].algo, + 'fichier': resultats[i].fichier, + 'cle': resultats[i].cle, + 'tentatives': resultats[i].nb_tentatives, + 'temps_execution': resultats[i].temps_execution, + 'taux_succes': resultats[i].taux_succes, + 'statut_succes' : 'Succès' if resultats[i].taux_succes > 60 else 'Echec', + 'texte_dechiffre' : resultats[i].texte_dechiffre + } + rapport_mission().generer_rapport_synthese(resultat) + progress.update(task, description="Mission complète effectuée.") # TODO: MAJ de la progress bar -> step: Mission complète effectuée + + # Mise à jour des statistiques globales + self.missions_completees.append({ + "dossier": dossier_chiffres, + "resultats": resultats, + "temps_total": time.time() - debut_mission + }) + + return resultats + + except Exception as e: + print(f"Erreur lors de la mission complète: {str(e)}") + return [] + + + def attaque_dictionnaire_manuelle(self, chemin_fichier: str, algorithme_choisi: str, chemin_dictionnaire: str) -> ResultatAnalyse: + """ + ATTAQUE PAR DICTIONNAIRE MANUELLE + - Choix du fichier et de l'algorithme + - Suivi en temps réel des tentatives + - Affichage des résultats intermédiaires + + Args: + chemin_fichier(str): chemin du fichier à attaquer + algorithme_choisi(str): algorithme à utiliser + + Returns: + ResultatAnalyse: résultat de l'attaque + """ + + + debut_attaque = time.time() + resultat = ResultatAnalyse("", b"", 0.0, b"", 0.0, 0) + + try: + if algorithme_choisi not in self.analyzers: + print(f"Algorithme {algorithme_choisi} non disponible") + return resultat + + analyzer = self.analyzers[algorithme_choisi] + + # Vérification de l'algorithme + score = analyzer.identifier_algo(chemin_fichier) + resultat.score_probabilite = score + resultat.algo = algorithme_choisi + print(f"Score de confirmation: {score:.2f}") + + if score < 0.3: + print("Score de confiance faible pour cet algorithme") + + # Génération des clés candidates + print(f"Génération des clés candidates") + cles_candidates = analyzer.generer_cles_candidates(chemin_dictionnaire) + print(f"{len(cles_candidates)} clés candidates générées") + + # Attaque par dictionnaire + + self.__tenter_dechiffrement_avec_dictionnaire(chemin_fichier, cles_candidates, analyzer, resultat) + + + temps_execution = time.time() - debut_attaque + resultat.temps_execution = temps_execution + print(f"Temps d'exécution: {temps_execution:.2f} secondes") + + return resultat + + except Exception as e: + print(f"Erreur lors de l'attaque: {str(e)}") + temps_execution = time.time() - debut_attaque + return ResultatAnalyse("", b"", 0.0, b"", temps_execution, 0) + + def attaque_dictionnaire(self,chemin_fichier_chiffrer: str, algo : str, chemin_dico : str = "keys/wordlist.txt"): + + with Progress() as progress: + analyzer = self.analyzers[algo] + + cle_candidates = analyzer.generer_cles_candidates(chemin_dico) + + with open(chemin_dico,'r') as d: + dico = d.readlines() + + with open(f"data/{chemin_fichier_chiffrer}",'rb') as f : + texte_chiffrer = f.read() + + task_id = progress.add_task("Testing...",total=len(cle_candidates)) + + current_task = 0 + + advance = 1 + + + while current_task < len(cle_candidates) : + time.sleep(0.5) + + essai_dechiffrage = analyzer.dechiffrer(f"data/{chemin_fichier_chiffrer}", cle_candidates[current_task]) + + if essai_dechiffrage != b"" : + + progress.update(task_id,advance=len(cle_candidates) - current_task) + + # Retourner un texte décodé/nettoyé pour affichage propre + return essai_dechiffrage.decode('utf-8', errors='ignore').replace('\x00', ' ') + + current_task+=1 + + progress.update(task_id,advance=advance) + + + return "Aucune clé trouvé" + + # print("\n Process is done ...") + + +print(DetecteurCryptoOrchestrateur().attaque_dictionnaire("mission1.enc","AES-CBC-256")) + From 2df619f216dd8296f5191c971d28caef64c28dc8 Mon Sep 17 00:00:00 2001 From: wesley-kami Date: Tue, 12 Aug 2025 22:36:00 +0100 Subject: [PATCH 13/14] uppercase Algorithms --- src/detecteur_crypto.py | 8 ++++---- src/interface_console.py | 13 ++++++++----- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/detecteur_crypto.py b/src/detecteur_crypto.py index 4c14803..2421675 100644 --- a/src/detecteur_crypto.py +++ b/src/detecteur_crypto.py @@ -47,10 +47,10 @@ def __init__(self): """ self.analyzers: dict[str, CryptoAnalyzer] = { "AES-CBC-256": Aes_Cbc_Analyzer(), - "ChaCha20": ChaCha20_Analyzer(), - "Blowfish": Blowfish_Analyzer(), + "CHACHA20": ChaCha20_Analyzer(), + "BLOWFISH": Blowfish_Analyzer(), "AES-GCM": Aes_Gcm_Analyzer(), - "Fernet": FernetAnalyzer(), + "FERNET": FernetAnalyzer(), } self.missions_completees: list[dict[str, Union[str, list[ResultatAnalyse], float]]] = [] self.statistiques_globales: dict[str, Union[int, float]] = { @@ -404,4 +404,4 @@ def attaque_dictionnaire(self,chemin_fichier_chiffrer: str, algo : str, chemin_d # print("\n Process is done ...") -print(DetecteurCryptoOrchestrateur().attaque_dictionnaire("mission1.enc","AES-CBC-256")) +print(DetecteurCryptoOrchestrateur().attaque_dictionnaire("mission5.enc","FERNET")) diff --git a/src/interface_console.py b/src/interface_console.py index 813a863..6893f14 100644 --- a/src/interface_console.py +++ b/src/interface_console.py @@ -134,13 +134,16 @@ def menu_2(self): def menu_3(self): self.console.clear() self.dynamiqueText("Attaque par dictionnaire manuelle","green") - self.dynamiqueText("Veuillez entrer le chemin du fichier :","white") - time.sleep(0.02) - # chemin_fichier = self.prompt.ask("Veuillez entrer le chemin du fichier : ") + self.dynamiqueText("Veuillez entrer le nom du fichier sur lequel l'attaque doit être effectuée","white") + # time.sleep(0.02) + chemin_fichier = self.prompt.ask(":") self.console.clear() self.dynamiqueText("Attaque en cours...","green") - time.sleep(0.02) - self.console.clear() + + self.prompt.ask("Quel algorithm souhaitez-vous appliquer sur ce fichier : ",choices=[]) + # time.sleep(0.02) + # self.console.clear() + DetecteurCryptoOrchestrateur().attaque_dictionnaire(f"data/{chemin_fichier}",) self.dynamiqueText("Attaque terminée","green") time.sleep(0.02) self.default_menu() From 7de4b6d38558e924c866dec2f04d9a9ddec08faa Mon Sep 17 00:00:00 2001 From: wesley-kami Date: Tue, 12 Aug 2025 23:04:30 +0100 Subject: [PATCH 14/14] =?UTF-8?q?int=C3=A9gration=20attaque=20dictionnaire?= =?UTF-8?q?=20+=20console?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/detecteur_crypto.py | 2 +- src/interface_console.py | 28 ++++++++++++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/detecteur_crypto.py b/src/detecteur_crypto.py index 2421675..6b1c2ce 100644 --- a/src/detecteur_crypto.py +++ b/src/detecteur_crypto.py @@ -404,4 +404,4 @@ def attaque_dictionnaire(self,chemin_fichier_chiffrer: str, algo : str, chemin_d # print("\n Process is done ...") -print(DetecteurCryptoOrchestrateur().attaque_dictionnaire("mission5.enc","FERNET")) +# print(DetecteurCryptoOrchestrateur().attaque_dictionnaire("mission5.enc","FERNET")) diff --git a/src/interface_console.py b/src/interface_console.py index 6893f14..524ca8e 100644 --- a/src/interface_console.py +++ b/src/interface_console.py @@ -9,7 +9,7 @@ from rich.table import Table from rich.progress import Progress from pathlib import Path -from tqdm import tqdm +# from tqdm import tqdm # from detecteur_crypto import Analyser_fichier_uniquement # from detecteur_crypto import Analyser_fichier_sequentiels from .detecteur_crypto import DetecteurCryptoOrchestrateur @@ -136,17 +136,29 @@ def menu_3(self): self.dynamiqueText("Attaque par dictionnaire manuelle","green") self.dynamiqueText("Veuillez entrer le nom du fichier sur lequel l'attaque doit être effectuée","white") # time.sleep(0.02) - chemin_fichier = self.prompt.ask(":") - self.console.clear() - self.dynamiqueText("Attaque en cours...","green") + pad=0 + while pad < self.calc_center(":missionN.enc"): + print(" ",end="") + pad+=1 + chemin_fichier = self.prompt.ask("") - self.prompt.ask("Quel algorithm souhaitez-vous appliquer sur ce fichier : ",choices=[]) + algo = self.prompt.ask("Veuillez saisir l'un des algorithmes suivant pour le déchiffrage",choices=["AES-CBC-256","CHACHA20","BLOWFISH","AES-GCM","FERNET"]).upper() + + self.dynamiqueText("Attaque en cours...","green") # time.sleep(0.02) # self.console.clear() - DetecteurCryptoOrchestrateur().attaque_dictionnaire(f"data/{chemin_fichier}",) + print(DetecteurCryptoOrchestrateur().attaque_dictionnaire(chemin_fichier,algo)) + self.dynamiqueText("Attaque terminée","green") - time.sleep(0.02) - self.default_menu() + + print("Veuillez saisir la touche ' Entrer ' afin de retourner au menu principale",end='') + esc = input("") + + if esc == "": + self.default_menu() + else : + self.default_menu() + def menu_4(self): self.console.clear()