Skip to content

Commit c15d2c2

Browse files
committed
fix: Correction des problèmes de typage
1 parent 093f12a commit c15d2c2

1 file changed

Lines changed: 68 additions & 106 deletions

File tree

src/analyzers/chacha20_analyzer.py

Lines changed: 68 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from rich import print
55
import os
66
import sys
7+
from typing import List
8+
79
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
810
from crypto_analyzer import CryptoAnalyzer
911
from utils import calculer_entropie
@@ -25,12 +27,10 @@ class ChaCha20_Analyzer(CryptoAnalyzer):
2527
_CHACHA20_LONGUEUR_BLOC: la taille du bloc de chiffrement (64 bits)
2628
"""
2729

28-
_CHACHA20_LONGUEUR_CLE = 32
29-
_CHACHA20_LONGUEUR_NONCE = 12 #fourni
30-
_CHACHA20_LONGUEUR_TAG = 16
31-
_CHACHA20_LONGUEUR_BLOC = 64
32-
33-
30+
_CHACHA20_LONGUEUR_CLE: int = 32
31+
_CHACHA20_LONGUEUR_NONCE: int = 12
32+
_CHACHA20_LONGUEUR_TAG: int = 16
33+
_CHACHA20_LONGUEUR_BLOC: int = 64
3434

3535
def identifier_algo(self, chemin_fichier_chiffre: str) -> float:
3636
"""
@@ -40,142 +40,104 @@ def identifier_algo(self, chemin_fichier_chiffre: str) -> float:
4040
- vérifiant l'absence de padding (pas de contrainte de taille)
4141
- vérifiant que la taille du fichier est suffisante pour contenir un nonce
4242
43-
Retourne une probabilité entre 0 et 1(Pour connaitre la probabilité que l'algo de chiffrement utilisé soit l'ChaCha20).
43+
Retourne une probabilité entre 0 et 1 (Pour connaitre la probabilité que l'algo de chiffrement utilisé soit l'ChaCha20).
4444
4545
Args:
46-
chemin_fichier_chiffre(str): le chemin du fichier chiffré à traiter .
46+
chemin_fichier_chiffre(str): le chemin du fichier chiffré à traiter.
4747
4848
Returns:
49-
float: La probabilité que l'algo de chiffrement utilisé soit l'ChaCha20 apres le calcul.
49+
float: La probabilité que l'algo de chiffrement utilisé soit l'ChaCha20 après le calcul.
5050
"""
5151
try:
5252
with open(chemin_fichier_chiffre, 'rb') as f:
53-
donnees = f.read()
53+
donnees: bytes = f.read()
5454

5555
if len(donnees) < self._CHACHA20_LONGUEUR_NONCE:
56-
return 0.0 # Fichier trop petit pour contenir un nonce
56+
return 0.0
5757

58-
# Extraire le nonce présumé (12 premiers bytes)
59-
nonce = donnees[:self._CHACHA20_LONGUEUR_NONCE]
60-
donnees_chiffrees = donnees[self._CHACHA20_LONGUEUR_NONCE:]
58+
nonce: bytes = donnees[:self._CHACHA20_LONGUEUR_NONCE]
59+
donnees_chiffrees: bytes = donnees[self._CHACHA20_LONGUEUR_NONCE:]
6160

6261
if len(donnees_chiffrees) == 0:
63-
return 0.0 # Pas de données chiffrées
62+
return 0.0
6463

65-
# Critère 1: Vérifier la taille minimale
64+
taille_min: float = 0.0
6665
if len(donnees) >= self._CHACHA20_LONGUEUR_NONCE + 16:
6766
taille_min = 1.0
68-
else:
69-
taille_min = 0.0
7067

71-
# Critère 2: Vérifier l'entropie des données chiffrées (doit être très élevée)
72-
entropie = calculer_entropie(donnees_chiffrees)
73-
# L'entropie d'un chiffrement ChaCha20 devrait être proche de 8 bits/octet
74-
if entropie / 8.0 > 1.0:
75-
entropie_max = 1.0
76-
else:
77-
entropie_max = entropie / 8.0
68+
entropie: float = calculer_entropie(donnees_chiffrees)
69+
entropie_max: float = min(entropie / 8.0, 1.0)
7870

79-
# Critère 3: Vérifier l'absence de padding (pas de contrainte de taille)
80-
# ChaCha20 est un chiffrement de flux, donc pas de padding
81-
# On vérifie que la taille des données chiffrées n'est pas un multiple d'une taille de bloc commune
82-
taille_donnees = len(donnees_chiffrees)
71+
padding_max: float = 1.0
72+
taille_donnees: int = len(donnees_chiffrees)
8373
if taille_donnees % 16 == 0 or taille_donnees % 8 == 0:
8474
padding_max = 0.5
85-
else:
86-
padding_max = 1.0
8775

88-
# Critère 4: Vérifier l'entropie du nonce (doit être élevée aussi)
89-
entropie_nonce = calculer_entropie(nonce)
90-
if entropie_nonce / 8.0 > 1.0:
91-
nonce_max = 1.0
92-
else:
93-
nonce_max = entropie_nonce / 8.0
76+
entropie_nonce: float = calculer_entropie(nonce)
77+
nonce_max: float = min(entropie_nonce / 8.0, 1.0)
9478

95-
# Calcul de la probabilité finale (moyenne pondérée des scores)
96-
probabilite = (taille_min * 0.1 +
79+
probabilite: float = (taille_min * 0.1 +
9780
entropie_max * 0.4 +
9881
padding_max * 0.3 +
9982
nonce_max * 0.2)
10083

101-
return min(probabilite, 1.0)
84+
return probabilite
10285

10386
except Exception as e:
10487
print(f"Erreur lors de l'identification de l'algorithme: {e}")
10588
return 0.0
10689

90+
def filtrer_dictionnaire_par_indices(self, chemin_fichier_chiffre: str) -> List[bytes]:
91+
# En supposant qu'elle retourne une liste de bytes pour les clés.
92+
return []
10793

108-
def filtrer_dictionnaire_par_indices(self, chemin_fichier_chiffre):
109-
pass
110-
111-
def generer_cles_candidates(self, chemin_fichier_chiffre):
112-
113-
'''
114-
Cette fonction se charge de générer les clés candidates pour le déchiffremment du fichier chiffré en utilisant
115-
la dérivation sha256 pour renforcer les clées de chiffrement.
94+
def generer_cles_candidates(self, chemin_dictionnaire: str) -> List[bytes]:
95+
"""
96+
Cette fonction se charge de générer les clés candidates pour le déchifremment du fichier chiffré en utilisant
97+
la dérivation sha256 pour renforcer les clées de chiffrement.
11698
117-
118-
Args:
119-
chemin_fichier_chiffre(str) : Le chemin vers le fichier chiffré
120-
121-
Returns:
122-
cles_candidates (list[bytes]) : Un tableau de clés, chaque clé étant une séquence d'octets
123-
'''
99+
Args:
100+
chemin_dictionnaire(str) : Le chemin vers le dictionnaire.
124101
125-
donnees_fichier_filtre = self.filtrer_dictionnaire_par_indices(chemin_fichier_chiffre)
126-
127-
cle_candidates: list[bytes] = []
102+
Returns:
103+
cles_candidates (List[bytes]) : Un tableau de clés, chaque clé étant une séquence d'octets.
104+
"""
105+
donnees_fichier_filtre: List[bytes] = self.filtrer_dictionnaire_par_indices(chemin_dictionnaire)
106+
cles_candidates: List[bytes] = []
128107
for cle in donnees_fichier_filtre:
129-
cle_candidates.append(hashlib.sha256(cle).digest())
130-
131-
return cle_candidates
108+
cles_candidates.append(hashlib.sha256(cle).digest())
109+
return cles_candidates
132110

133111
def dechiffrer(self, chemin_fichier_chiffre: str, cle_donnee: bytes) -> bytes:
134112
if len(cle_donnee) != 32:
135113
raise ValueError("Erreur : La clé n'a pas la taille correcte")
136-
else:
137-
try:
138-
# Utiliser le chemin complet si c'est un chemin absolu, sinon ajouter le préfixe data/
139-
if os.path.isabs(chemin_fichier_chiffre):
140-
fichier_path = chemin_fichier_chiffre
141-
else:
142-
fichier_path = f"data/{chemin_fichier_chiffre}"
143-
144-
with open(fichier_path, 'rb') as f:
145-
nonce = f.read(self._CHACHA20_LONGUEUR_NONCE)
146-
texte_chiffre = f.read()
147-
148-
algorithm_chacha20 = algorithms.ChaCha20(cle_donnee, nonce)
149-
cipher = Cipher(algorithm_chacha20, mode=None)
150-
decrypteur = cipher.decryptor()
151-
resultat = decrypteur.update(texte_chiffre)
152-
153-
# Retourner les bytes bruts comme attendu par l'interface
154-
return resultat
155-
156-
except Exception as e:
157-
print(f"Une erreur est survenue : {e}")
158-
return b""
159-
cle_candidates.append(hashlib.sha256(cle).encode(encoding="utf-8"))
160-
161-
return cle_candidates
162-
163-
def dechiffrer(self,chemin_fichier_chiffer : str ,clef :bytes)->str:
164-
if len(clef) != 32 : return ValueError("Erreur : La clé a pas la taille correcte ")
165-
else:
166-
try:
167-
with open(f"data/{chemin_fichier_chiffer}",'rb') as f:
168-
nonce = f.read(16)
169-
texte_chiffrer = f.read()
170-
171-
counter=0
172-
algorithm_chacha20 = algorithms.ChaCha20(clef,nonce)
173-
cipher = Cipher(algorithm_chacha20,mode=None)
174-
decrypteur = cipher.decryptor()
175-
return decrypteur.update(texte_chiffrer)
176-
except Exception as e:
177-
print(f"Une erreur est survenu : {e}")
178-
179-
114+
115+
try:
116+
fichier_path: str = chemin_fichier_chiffre
117+
if not os.path.isabs(chemin_fichier_chiffre):
118+
fichier_path = f"data/{chemin_fichier_chiffre}"
119+
120+
with open(fichier_path, 'rb') as f:
121+
nonce: bytes = f.read(self._CHACHA20_LONGUEUR_NONCE)
122+
texte_chiffre: bytes = f.read()
123+
124+
algorithm_chacha20 = algorithms.ChaCha20(cle_donnee, nonce)
125+
cipher = Cipher(algorithm_chacha20, mode=None)
126+
decrypteur = cipher.decryptor()
127+
resultat: bytes = decrypteur.update(texte_chiffre)
128+
129+
return resultat
180130

181-
print(ChaCha20_Analyzer().dechiffrer("mission2.enc",os.urandom(32)))
131+
except Exception as e:
132+
print(f"Une erreur est survenue : {e}")
133+
return b""
134+
135+
# L'appel direct a été déplacé dans un bloc if __name__ == "__main__" pour de bonnes pratiques (Mouwafic)
136+
if __name__ == "__main__":
137+
try:
138+
resultat_dechiffrement: bytes = ChaCha20_Analyzer().dechiffrer("mission2.enc", os.urandom(32))
139+
print(f"Résultat du déchiffrement : {resultat_dechiffrement.decode('utf-8')}")
140+
except ValueError as ve:
141+
print(ve)
142+
except FileNotFoundError:
143+
print("Erreur: Le fichier 'mission2.enc' est introuvable.")

0 commit comments

Comments
 (0)