🔐 TP : OPÉRATION CRYPTEX - Mission de Chiffrement

📋 Contexte de la mission

L’annĂ©e est 1942. Vous ĂȘtes un cryptographe de la RĂ©sistance française chargĂ© de dĂ©velopper un systĂšme de communication sĂ©curisĂ© pour transmettre des messages entre les diffĂ©rents rĂ©seaux. Votre objectif : crĂ©er un programme en C capable de chiffrer, dĂ©chiffrer et analyser des messages en utilisant le chiffre de VigenĂšre, une technique rĂ©putĂ©e incassable Ă  l’époque !

Temps estimé : 4-6 heures
Niveau : Intermédiaire
Compétences visées : Manipulation de tableaux, chaßnes de caractÚres, algorithmes, structures de contrÎle


🎯 Objectifs pĂ©dagogiques

À la fin de ce TP, vous serez capable de :

  • ✅ Manipuler des tableaux statiques mono et multidimensionnels
  • ✅ Traiter des chaĂźnes de caractĂšres complexes
  • ✅ ImplĂ©menter des algorithmes de chiffrement
  • ✅ CrĂ©er des fonctions modulaires et rĂ©utilisables
  • ✅ GĂ©rer les entrĂ©es/sorties utilisateur
  • ✅ DĂ©boguer et tester mĂ©thodiquement votre code

📐 Contraintes techniques OBLIGATOIRES

RĂšgles strictes

  • ❌ INTERDICTION d’utiliser malloc, calloc, ou tout pointeur dynamique
  • ✅ UNIQUEMENT des tableaux statiques (dĂ©clarĂ©s avec une taille fixe)
  • ✅ Taille maximale du message : 500 caractĂšres
  • ✅ Taille maximale de la clĂ© : 100 caractĂšres
  • ✅ Utilisation des bibliothĂšques standard autorisĂ©es : stdio.h, string.h, ctype.h, stdlib.h

Structure du projet

Votre code doit ĂȘtre organisĂ© ainsi :

projet_cryptex/
├── cryptex.c          (fichier principal)
└── tests.txt          (exemples de tests)

đŸ› ïž FonctionnalitĂ©s Ă  implĂ©menter

Phase 1 : Fonctions de base

1.1 - Préparation du texte

void nettoyer_texte(char texte[], char resultat[]);

RÎle : Prépare le texte pour le chiffrement

  • Supprime les accents : é→e, à→a, ç→c, etc.
  • PrĂ©serve les espaces et la ponctuation
  • Convertit tout en MAJUSCULES pour simplifier
  • Exemple : "Rendez-vous Ă  18h!" → "RENDEZ-VOUS A 18H!"

1.2 - Validation de la clé

int valider_cle(char cle[]);

RÎle : Vérifie que la clé est valide

  • Retourne 1 si la clĂ© ne contient que des lettres
  • Retourne 0 sinon
  • Affiche un message d’erreur explicite si invalide

1.3 - Chiffrement de VigenĂšre

void chiffrer_vigenere(char message[], char cle[], char resultat[]);

RĂŽle : Chiffre le message selon l’algorithme de VigenĂšre L’algorithme de VigenĂšre expliquĂ©

  • Formule : C[i] = (M[i] + K[i mod len(K)]) mod 26

  • Les caractĂšres non-alphabĂ©tiques restent inchangĂ©s

  • PrĂ©serve les espaces et la ponctuation

  • Exemple dĂ©taillĂ© :

    Message : BONJOUR
    Clé :     SECRET (répétée : SECRETS)
    
    B + S = 1 + 18 = 19 → T
    O + E = 14 + 4 = 18 → S
    N + C = 13 + 2 = 15 → P
    J + R = 9 + 17 = 26 → A (mod 26)
    O + E = 14 + 4 = 18 → S
    U + T = 20 + 19 = 39 → N (39 mod 26 = 13)
    R + S = 17 + 18 = 35 → J (35 mod 26 = 9)
    
    Résultat : TSPASNI
    

1.4 - Déchiffrement de VigenÚre

void dechiffrer_vigenere(char chiffre[], char cle[], char resultat[]);

RĂŽle : Inverse le chiffrement

  • Formule : M[i] = (C[i] - K[i mod len(K)] + 26) mod 26
  • Le +26 Ă©vite les valeurs nĂ©gatives

Phase 2 : Analyse cryptographique

2.1 - Analyse de fréquence

void analyser_frequences(char texte[], int frequences[26], int *total_lettres);

Rîle : Compte l’occurrence de chaque lettre

  • Remplit un tableau de 26 cases (A-Z)

  • Ignore la casse, espaces et ponctuation

  • Met Ă  jour le nombre total de lettres via le pointeur

  • Exemple :

    Texte : "HELLO WORLD"
    Fréquences : A=0, B=0, C=0, D=1, E=1, ..., L=3, O=2, ...
    Total : 10 lettres
    

2.2 - Affichage graphique avancé

void afficher_histogramme(int frequences[26], int total);

RÎle : Affiche un histogramme ASCII stylisé

  • Affiche les barres proportionnelles

  • Indique le pourcentage de chaque lettre

  • N’affiche que les lettres prĂ©sentes (frĂ©quence > 0)

  • Format attendu :

    === ANALYSE DES FRÉQUENCES ===
    Total : 245 lettres analysées
    A: ████████████ 12.2% (30)
    E: ████████████████████ 18.8% (46)
    L: ██████ 5.7% (14)
    O: ████████ 8.2% (20)...
    

2.3 - Calcul de l’indice de coïncidence

float calculer_indice_coincidence(char texte[]);

RĂŽle : Calcule l’IC pour deviner la longueur de la clĂ©

  • Formule : IC = ÎŁ(ni * (ni-1)) / (N * (N-1))
  • IC ≈ 0.067 pour un texte français
  • IC ≈ 0.038 pour un texte chiffrĂ© avec VigenĂšre
  • Aide Ă  dĂ©terminer si le texte est chiffrĂ© ou non

Phase 3 : Attaque cryptanalytique

3.1 - Détection de mots-clés

int contient_mots_francais(char texte[]);

RÎle : Vérifie si le texte contient des mots français courants

  • Cherche au moins 3 mots parmi : “LE”, “DE”, “UN”, “ET”, “DANS”, “QUE”, “EST”, “POUR”, “PAR”, “SUR”
  • Retourne le nombre de mots trouvĂ©s
  • Utile pour valider un dĂ©chiffrement

3.2 - Force brute intelligente

void attaque_force_brute(char message_chiffre[], int longueur_cle_max);

RĂŽle : Tente de casser le chiffrement

  • Teste toutes les clĂ©s de longueur 1 Ă  longueur_cle_max (max 4)

  • Affiche uniquement les rĂ©sultats contenant des mots français

  • Limite : 26^4 = 456 976 combinaisons max (pour longueur 4)

  • Affichage attendu :

    🔍 RECHERCHE EN COURS... (longueur de clĂ© : 3)
    
    ✓ ClĂ© possible trouvĂ©e : "CLE"  
    → "LE MESSAGE EST CLAIR ET CONTIENT DES MOTS"  
    → Score : 5 mots français dĂ©tectĂ©s
    
    ✓ ClĂ© possible trouvĂ©e : "MOT"  
    → "JK FQCCYMQ QCN NRZMX QD LKJNMQJN BQC SUD"  
    → Score : 2 mots français dĂ©tectĂ©s
    

Phase 4 : Interface utilisateur

4.1 - Menu principal interactif

void afficher_menu();
int lire_choix();

Menu complet attendu :

╔═══════════════════════════════════════════╗
║   🔐 OPÉRATION CRYPTEX - V2.0 🔐         ║
║   SystĂšme de chiffrement de la RĂ©sistance ║
╚═══════════════════════════════════════════╝

[1] 📝 Chiffrer un message
[2] 🔓 DĂ©chiffrer un message
[3] 📊 Analyser les frĂ©quences d'un texte
[4] 🔍 Attaque par force brute
[5] 📖 Afficher l'aide
[6] đŸšȘ Quitter le programme

Votre choix : 

4.2 - Gestion des erreurs

  • VĂ©rifier que le message ne dĂ©passe pas 500 caractĂšres
  • VĂ©rifier que la clĂ© ne dĂ©passe pas 100 caractĂšres
  • Valider que la clĂ© ne contient que des lettres
  • GĂ©rer les entrĂ©es invalides dans le menu
  • Afficher des messages d’erreur clairs et explicites

đŸ§Ș Tests obligatoires Ă  rĂ©aliser

Test 1 : Chiffrement basique

Message : "ATTAQUE A L AUBE"
Clé : "SECRET"
Résultat attendu : "SXVEEIW S T SYFX"

Test 2 : Message avec ponctuation

Message : "Rendez-vous demain, 18h30!"
Clé : "RESISTANCE"
Résultat attendu : "ISKASL-EMFG UVQRTN, 18U30!"

Test 3 : Réversibilité

Chiffrer puis dĂ©chiffrer avec la mĂȘme clĂ© doit redonner le message original.

Test 4 : Analyse de fréquence

Sur le texte : “ELLE EST ALLEE A LA PLAGE”

  • E devrait ĂȘtre la lettre la plus frĂ©quente
  • L et A Ă©galement bien reprĂ©sentĂ©es

Test 5 : Attaque force brute

Sur un message chiffrĂ© avec une clĂ© de 3 lettres, l’attaque doit retrouver la bonne clĂ©.


📚 Aide et ressources

L’algorithme de VigenĂšre expliquĂ©

Principe : Chaque lettre de la clĂ© dĂ©cale les lettres du message d’un certain rang.

Table de correspondance :

A=0, B=1, C=2, D=3, E=4, F=5, G=6, H=7, I=8, J=9,
K=10, L=11, M=12, N=13, O=14, P=15, Q=16, R=17,
S=18, T=19, U=20, V=21, W=22, X=23, Y=24, Z=25

Exemple pas Ă  pas :

Message : "SALUT"
Clé : "CLE" (répétée : "CLECL")

S (18) + C (2) = 20 → U
A (0)  + L (11) = 11 → L
L (11) + E (4) = 15 → P
U (20) + C (2) = 22 → W
T (19) + L (11) = 30 → 30 mod 26 = 4 → E

Résultat : "ULPWE"

Fonctions utiles

toupper(c)    // Convertit en majuscule
tolower(c)    // Convertit en minuscule
isalpha(c)    // Vérifie si c'est une lettre
strlen(s)     // Longueur d'une chaĂźne
strcpy(d, s)  // Copie une chaĂźne
strstr(s, sub)// Cherche une sous-chaĂźne

🎁 BONUS (facultatifs, +20% max)

Bonus 1 : Historique des messages (5%)

void sauvegarder_historique(char messages[][500], int *nb_messages, char nouveau[]);
void afficher_historique(char messages[][500], int nb_messages);

Stocker les 10 derniers messages traités dans un tableau 2D.

Bonus 2 : Chiffre de César intégré (5%)

void chiffrer_cesar(char message[], int decalage, char resultat[]);

Ajouter une option pour chiffrer avec César (cas particulier de VigenÚre).

Bonus 3 : Détection automatique de la longueur de clé (5%)

int deviner_longueur_cle(char message_chiffre[]);

Utiliser la mĂ©thode de Kasiski ou l’IC pour estimer la longueur de la clĂ©.

Bonus 4 : Export des résultats (5%)

void exporter_vers_fichier(char message[], char cle[], char resultat[]);

Sauvegarder les résultats dans un fichier resultats.txt.