Skip to content
Merged
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
80c1f1b
Intégration de AesCbcAnalyzer dans DetecteurCryptoOrchestrateur.
Eunock-web Aug 2, 2025
83cc501
Merge branch 'feature/consoleInterface' of https://github.com/mouwafi…
Eunock-web Aug 2, 2025
a41256c
Debut de l'implementation du code dans la classe principale avec le menu
Eunock-web Aug 2, 2025
f40bb59
Documentation de la fonction d'entropie
e-mandy Aug 2, 2025
0474003
Merge branch 'feature/calculerEntropieShannon' of https://github.com/…
e-mandy Aug 2, 2025
cac3bf5
Suite de l'implementation du code dans la classe principale avec le menu
Eunock-web Aug 2, 2025
8f0dbfc
Essai de fusion (1/2)
e-mandy Aug 2, 2025
eadb52d
Fusion (2/2)
e-mandy Aug 3, 2025
b638a49
Récupération du main (1/2)
e-mandy Aug 3, 2025
ecf4eef
Récupération du main (2/2)
e-mandy Aug 3, 2025
e965801
Mise en place des tests unitaires (1/4)
e-mandy Aug 3, 2025
e119f5d
Revert "Mise en place des tests unitaires (1/4)"
e-mandy Aug 3, 2025
14e759d
Mise en place des tests unitaires (1/4)
e-mandy Aug 3, 2025
3d6332f
Merge branch 'main' of https://github.com/mouwaficbdr/CryptoForensic-…
e-mandy Aug 4, 2025
93fd27d
Update de l'option quitter
wesley-kami Aug 4, 2025
77102c5
Merge branch 'main' of https://github.com/mouwaficbdr/CryptoForensic-…
wesley-kami Aug 4, 2025
52433f7
Mise en place des tests liés à l'analyzer aes cbc
e-mandy Aug 4, 2025
af85ee2
Corrections de typage et de logique
mouwaficbdr Aug 4, 2025
896696a
Correction du comportement à la levée de l'exception
mouwaficbdr Aug 4, 2025
3391403
Correction de la lgoque de test de test_exception_déchiffrer
mouwaficbdr Aug 4, 2025
9b38d27
Corection de la logique de test_verification_texte_dechiffre
mouwaficbdr Aug 4, 2025
275b47a
fix: Utilisation de pathlib pour une gestion portable des chemins.
mouwaficbdr Aug 4, 2025
d662e06
Merge branch 'main' into feature/testsUnitaires
mouwaficbdr Aug 4, 2025
c1c0b22
Revu des fonctions pour une meilleure optimisation
Eunock-web Aug 5, 2025
b8c337b
Creation de la classe Chacha20_Analyzer
Eunock-web Aug 5, 2025
abb4365
Merge branch 'feature/DetecteurCryptoOrchestrateur' of https://github…
wesley-kami Aug 5, 2025
b74715c
Ajout du guide d'utilisation
wesley-kami Aug 5, 2025
5c9e9bb
Merge branch 'main' of https://github.com/mouwaficbdr/CryptoForensic-…
wesley-kami Aug 5, 2025
243ec7f
Fusion de la branch main
e-mandy Aug 5, 2025
ed453b1
Unsaved files
e-mandy Aug 5, 2025
d0e307e
Mise en place de la fonction de génération de clés candidates
e-mandy Aug 6, 2025
fd73f32
Merge branch 'main' of https://github.com/mouwaficbdr/CryptoForensic-…
wesley-kami Aug 6, 2025
2ad2af3
Merge branch 'feature/chacha20_analyzer' of https://github.com/mouwaf…
wesley-kami Aug 6, 2025
3ac1830
prémices du déchiffrement Chacha20
wesley-kami Aug 6, 2025
8e3e468
logique ddecryptage
wesley-kami Aug 7, 2025
3bb38e2
Merge branch 'main' into feature/chacha20_analyzer
wesley-kami Aug 7, 2025
b361f1a
Implementation de la fonction identifier_algo dans la classe chacha20…
Eunock-web Aug 7, 2025
6ba0a41
Correction des erreurs dans la fonction identifier_algo
Eunock-web Aug 7, 2025
64611ee
Merge branch 'main' into feature/chacha20_analyzer
Eunock-web Aug 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 134 additions & 4 deletions src/analyzers/chacha20_analyzer.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,116 @@
# Import des modules
import hashlib
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from rich import print
import os, struct
import math
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from crypto_analyzer import CryptoAnalyzer
from utils import calculer_entropie

# Définition de la classe ChaCha20_Analyzer
class ChaCha20_Analyzer(CryptoAnalyzer):
"""
Détermine si l'algo ChaCha20 est utilisé, génère des clés et tente de de déchffrer un fichier chiffré en utilisant les clés générées.

Cette classe a trois méthodes:
- identifier_algo: Détermine si l'algo de chiffrement utilisé sur le fichier chiffré qui lui est passé en paramètre est l'ChaCha20.
- generer_cles_candidates: Génère une liste de clés candidates pour le déchiffrement du fichier chiffré
- dechiffrer: fait le déchiffrement proprement dit sur la base de la liste des clés générées

Attributes:
_CHACHA20_LONGUEUR_CLE: la taille de la clé de chiffrement (32 octets)
_CHACHA20_LONGUEUR_NONCE: la taille du vecteur d'initialisation (12 octets)
_CHACHA20_LONGUEUR_TAG: la taille de l'empreinte de chiffrement (16 octets)
_CHACHA20_LONGUEUR_BLOC: la taille du bloc de chiffrement (64 bits)
"""

_CHACHA20_LONGUEUR_CLE = 32
_CHACHA20_LONGUEUR_NONCE = 12 #fourni
_CHACHA20_LONGUEUR_TAG = 16
_CHACHA20_LONGUEUR_BLOC = 64



def identifier_algo(self, chemin_fichier_chiffre: str) -> float:
"""
Détermine la probabilité que l'algo de chiffrement utilisé soit l'ChaCha20 en:
- vérifiant la présence d'un nonce de 12 bytes en début de fichier
- vérifiant l'entropie très élevée sur l'ensemble des données
- vérifiant l'absence de padding (pas de contrainte de taille)
- vérifiant que la taille du fichier est suffisante pour contenir un nonce

Retourne une probabilité entre 0 et 1(Pour connaitre la probabilité que l'algo de chiffrement utilisé soit l'ChaCha20).

Args:
chemin_fichier_chiffre(str): le chemin du fichier chiffré à traiter .

Returns:
float: La probabilité que l'algo de chiffrement utilisé soit l'ChaCha20 apres le calcul.
"""
try:
with open(chemin_fichier_chiffre, 'rb') as f:
donnees = f.read()

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

# Extraire le nonce présumé (12 premiers bytes)
nonce = donnees[:self._CHACHA20_LONGUEUR_NONCE]
donnees_chiffrees = donnees[self._CHACHA20_LONGUEUR_NONCE:]

if len(donnees_chiffrees) == 0:
return 0.0 # Pas de données chiffrées

# Critère 1: Vérifier la taille minimale
if len(donnees) >= self._CHACHA20_LONGUEUR_NONCE + 16:
taille_min = 1.0
else:
taille_min = 0.0

# Critère 2: Vérifier l'entropie des données chiffrées (doit être très élevée)
entropie = calculer_entropie(donnees_chiffrees)
# L'entropie d'un chiffrement ChaCha20 devrait être proche de 8 bits/octet
if entropie / 8.0 > 1.0:
entropie_max = 1.0
else:
entropie_max = entropie / 8.0

# Critère 3: Vérifier l'absence de padding (pas de contrainte de taille)
# ChaCha20 est un chiffrement de flux, donc pas de padding
# On vérifie que la taille des données chiffrées n'est pas un multiple d'une taille de bloc commune
taille_donnees = len(donnees_chiffrees)
if taille_donnees % 16 == 0 or taille_donnees % 8 == 0:
padding_max = 0.5
else:
padding_max = 1.0

# Critère 4: Vérifier l'entropie du nonce (doit être élevée aussi)
entropie_nonce = calculer_entropie(nonce)
if entropie_nonce / 8.0 > 1.0:
nonce_max = 1.0
else:
nonce_max = entropie_nonce / 8.0

# Calcul de la probabilité finale (moyenne pondérée des scores)
probabilite = (taille_min * 0.1 +
entropie_max * 0.4 +
padding_max * 0.3 +
nonce_max * 0.2)

return min(probabilite, 1.0)

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

class ChaCha20_Analyzer:

def filtrer_dictionnaire_par_indices(self, chemin_fichier_chiffre):
pass

def generer_cles_candidates(self, chemin_fichier_chiffre):


def generer_cle_candidates(self, chemin_fichier_chiffre):
'''
Cette fonction se charge de générer les clés candidates pour le déchiffremment du fichier chiffré en utilisant
la dérivation sha256 pour renforcer les clées de chiffrement.
Expand All @@ -21,13 +121,42 @@ def generer_cle_candidates(self, chemin_fichier_chiffre):

Returns:
cles_candidates (list[bytes]) : Un tableau de clés, chaque clé étant une séquence d'octets

'''

donnees_fichier_filtre = self.filtrer_dictionnaire_par_indices(chemin_fichier_chiffre)

cle_candidates: list[bytes] = []
for cle in donnees_fichier_filtre:
cle_candidates.append(hashlib.sha256(cle).digest())

return cle_candidates

def dechiffrer(self, chemin_fichier_chiffre: str, cle_donnee: bytes) -> bytes:
if len(cle_donnee) != 32:
raise ValueError("Erreur : La clé n'a pas la taille correcte")
else:
try:
# Utiliser le chemin complet si c'est un chemin absolu, sinon ajouter le préfixe data/
if os.path.isabs(chemin_fichier_chiffre):
fichier_path = chemin_fichier_chiffre
else:
fichier_path = f"data/{chemin_fichier_chiffre}"

with open(fichier_path, 'rb') as f:
nonce = f.read(self._CHACHA20_LONGUEUR_NONCE)
texte_chiffre = f.read()

algorithm_chacha20 = algorithms.ChaCha20(cle_donnee, nonce)
cipher = Cipher(algorithm_chacha20, mode=None)
decrypteur = cipher.decryptor()
resultat = decrypteur.update(texte_chiffre)

# Retourner les bytes bruts comme attendu par l'interface
return resultat

except Exception as e:
print(f"Une erreur est survenue : {e}")
return b""
cle_candidates.append(hashlib.sha256(cle).encode(encoding="utf-8"))

return cle_candidates
Expand All @@ -52,4 +181,5 @@ def dechiffrer(self,chemin_fichier_chiffer : str ,clef :bytes)->str:
print(f"Une erreur est survenu : {e}")



# print(ChaCha20_Analyzer().dechiffrer("mission2.enc",os.urandom(32)))