55import os , struct
66import math
77
8- # Import de la classe CryptoAnalyzer
9- from ..crypto_analyzer import CryptoAnalyzer
8+ # Import de la classe CryptoAnalyzer et utils
9+ import sys
10+ import os
11+ sys .path .append (os .path .join (os .path .dirname (__file__ ), '..' ))
12+ from crypto_analyzer import CryptoAnalyzer
13+ from utils import calculer_entropie
1014
1115# Définition de la classe ChaCha20_Analyzer
1216class ChaCha20_Analyzer (CryptoAnalyzer ):
@@ -30,34 +34,7 @@ class ChaCha20_Analyzer(CryptoAnalyzer):
3034 _CHACHA20_LONGUEUR_TAG = 16
3135 _CHACHA20_LONGUEUR_BLOC = 64
3236
33- def calculer_entropie (self , data : bytes ) -> float :
34- """
35- Calcule l'entropie de Shannon d'une séquence d'octets.
36-
37- Args:
38- data (bytes): Les données à analyser
39-
40- Returns:
41- float: L'entropie calculée (0-8 bits par octet)
42- """
43- if not data :
44- return 0.0
45-
46- # Compter les occurrences de chaque octet
47- compteur = [0 ] * 256
48- for byte in data :
49- compteur [byte ] += 1
50-
51- # Calculer l'entropie
52- entropie = 0.0
53- longueur = len (data )
54-
55- for count in compteur :
56- if count > 0 :
57- probabilite = count / longueur
58- entropie -= probabilite * math .log2 (probabilite )
59-
60- return entropie
37+
6138
6239 def identifier_algo (self , chemin_fichier_chiffre : str ) -> float :
6340 """
@@ -83,39 +60,47 @@ def identifier_algo(self, chemin_fichier_chiffre: str) -> float:
8360 return 0.0 # Fichier trop petit pour contenir un nonce
8461
8562 # Extraire le nonce présumé (12 premiers bytes)
86- nonce_presume = donnees [:self ._CHACHA20_LONGUEUR_NONCE ]
63+ nonce = donnees [:self ._CHACHA20_LONGUEUR_NONCE ]
8764 donnees_chiffrees = donnees [self ._CHACHA20_LONGUEUR_NONCE :]
8865
8966 if len (donnees_chiffrees ) == 0 :
9067 return 0.0 # Pas de données chiffrées
9168
92- # Critère 1: Vérifier la taille minimale (nonce + au moins quelques bytes de données)
93- score_taille = 1.0 if len (donnees ) >= self ._CHACHA20_LONGUEUR_NONCE + 16 else 0.0
69+ # Critère 1: Vérifier la taille minimale
70+ if len (donnees ) >= self ._CHACHA20_LONGUEUR_NONCE + 16 :
71+ taille_min = 1.0
72+ else :
73+ taille_min = 0.0
9474
9575 # Critère 2: Vérifier l'entropie des données chiffrées (doit être très élevée)
96- entropie = self . calculer_entropie (donnees_chiffrees )
76+ entropie = calculer_entropie (donnees_chiffrees )
9777 # L'entropie d'un chiffrement ChaCha20 devrait être proche de 8 bits/octet
98- score_entropie = min (entropie / 8.0 , 1.0 )
78+ if entropie / 8.0 > 1.0 :
79+ entropie_max = 1.0
80+ else :
81+ entropie_max = entropie / 8.0
9982
10083 # Critère 3: Vérifier l'absence de padding (pas de contrainte de taille)
10184 # ChaCha20 est un chiffrement de flux, donc pas de padding
10285 # On vérifie que la taille des données chiffrées n'est pas un multiple d'une taille de bloc commune
10386 taille_donnees = len (donnees_chiffrees )
104- score_padding = 1.0 # Par défaut, on suppose pas de padding
105-
106- # Vérifier si la taille est un multiple de tailles de bloc communes (AES = 16, DES = 8)
10787 if taille_donnees % 16 == 0 or taille_donnees % 8 == 0 :
108- score_padding = 0.5 # Réduire le score si c'est un multiple de tailles de bloc communes
88+ padding_max = 0.5
89+ else :
90+ padding_max = 1.0
10991
11092 # Critère 4: Vérifier l'entropie du nonce (doit être élevée aussi)
111- entropie_nonce = self .calculer_entropie (nonce_presume )
112- score_nonce = min (entropie_nonce / 8.0 , 1.0 )
93+ entropie_nonce = calculer_entropie (nonce )
94+ if entropie_nonce / 8.0 > 1.0 :
95+ nonce_max = 1.0
96+ else :
97+ nonce_max = entropie_nonce / 8.0
11398
11499 # Calcul de la probabilité finale (moyenne pondérée des scores)
115- probabilite = (score_taille * 0.1 +
116- score_entropie * 0.4 +
117- score_padding * 0.3 +
118- score_nonce * 0.2 )
100+ probabilite = (taille_min * 0.1 +
101+ entropie_max * 0.4 +
102+ padding_max * 0.3 +
103+ nonce_max * 0.2 )
119104
120105 return min (probabilite , 1.0 )
121106
@@ -126,7 +111,7 @@ def identifier_algo(self, chemin_fichier_chiffre: str) -> float:
126111 def filtrer_dictionnaire_par_indices (self , chemin_fichier_chiffre ):
127112 pass
128113
129- def generer_cle_candidates (self , chemin_fichier_chiffre ):
114+ def generer_cles_candidates (self , chemin_fichier_chiffre ):
130115 '''
131116 Cette fonction se charge de générer les clés candidates pour le déchiffremment du fichier chiffré en utilisant
132117 la dérivation sha256 pour renforcer les clées de chiffrement.
@@ -146,29 +131,32 @@ def generer_cle_candidates(self, chemin_fichier_chiffre):
146131
147132 return cle_candidates
148133
149- def dechiffrer (self , chemin_fichier_chiffre : str , clef : bytes ) -> str :
150- if len (clef ) != 32 :
134+ def dechiffrer (self , chemin_fichier_chiffre : str , cle_donnee : bytes ) -> bytes :
135+ if len (cle_donnee ) != 32 :
151136 raise ValueError ("Erreur : La clé n'a pas la taille correcte" )
152137 else :
153138 try :
154- with open (f"data/{ chemin_fichier_chiffre } " , 'rb' ) as f :
139+ # Utiliser le chemin complet si c'est un chemin absolu, sinon ajouter le préfixe data/
140+ if os .path .isabs (chemin_fichier_chiffre ):
141+ fichier_path = chemin_fichier_chiffre
142+ else :
143+ fichier_path = f"data/{ chemin_fichier_chiffre } "
144+
145+ with open (fichier_path , 'rb' ) as f :
155146 nonce = f .read (self ._CHACHA20_LONGUEUR_NONCE )
156147 texte_chiffre = f .read ()
157148
158- algorithm_chacha20 = algorithms .ChaCha20 (clef , nonce )
149+ algorithm_chacha20 = algorithms .ChaCha20 (cle_donnee , nonce )
159150 cipher = Cipher (algorithm_chacha20 , mode = None )
160151 decrypteur = cipher .decryptor ()
161152 resultat = decrypteur .update (texte_chiffre )
162153
163- # Essayer de décoder en UTF-8 avec gestion d'erreurs
164- try :
165- return resultat .decode ('utf-8' )
166- except UnicodeDecodeError :
167- return resultat .decode ('utf-8' , errors = 'ignore' )
154+ # Retourner les bytes bruts comme attendu par l'interface
155+ return resultat
168156
169157 except Exception as e :
170158 print (f"Une erreur est survenue : { e } " )
171- return None
159+ return b""
172160
173161
174162# print(ChaCha20_Analyzer().dechiffrer("mission2.enc",os.urandom(32)))
0 commit comments