Chiffre de Vigenère : identifier et déchiffrer
Le chiffre de Vigenère applique une série de décalages alphabétiques (chiffre de César) dont la valeur change à chaque lettre selon une clé qui se répète cycliquement. Le texte chiffré produit résiste à une simple analyse de fréquence, contrairement au César.
Principe
Section intitulée « Principe »Le chiffrement consiste à décaler chaque lettre du message clair d’une valeur définie par la lettre correspondante de la clé, en cyclant sur la clé si le message est plus long.
Chiffrement :
position chiffrée = (position claire + position clé) mod 26Déchiffrement :
position claire = (position chiffrée - position clé + 26) mod 26Exemple avec la clé KEY :
Message clair : H E L L OClé (cyclique) : K E Y K EDécalages : +10 +4 +24 +10 +4Message chiffré: R I J V SLa lettre H (position 7) décalée de K (10) donne R (17). La clé se répète : après Y, elle repart à K.
Identifier un texte chiffré par Vigenère
Section intitulée « Identifier un texte chiffré par Vigenère »Caractéristiques visuelles
Section intitulée « Caractéristiques visuelles »Un texte chiffré par Vigenère :
- Ne contient que des lettres (majuscules ou minuscules selon l’implémentation)
- Ne présente pas de mots reconnaissables
- Affiche une distribution de fréquences plus aplatie qu’un texte en clair, mais pas uniformément plate (contrairement à un One-Time Pad)
Indice de coïncidence
Section intitulée « Indice de coïncidence »L’indice de coïncidence (IC) mesure la probabilité que deux lettres tirées au hasard dans le texte soient identiques. Un texte en langue naturelle a un IC caractéristique :
- Français : IC ≈ 0.074
- Anglais : IC ≈ 0.065
- Texte chiffré par César ou substitution monoalphabétique : IC ≈ 0.065 (la distribution est conservée)
- Texte chiffré par Vigenère (clé longue) : IC ≈ 0.038 (distribution aplatie)
- Texte aléatoire : IC ≈ 0.038
Un IC compris entre 0.04 et 0.06 sur un texte alphabétique évoque un chiffrement polyalphabétique comme Vigenère.
from collections import Counter
def indice_coincidence(texte): texte = texte.upper().replace(' ', '') n = len(texte) freq = Counter(texte) ic = sum(f * (f - 1) for f in freq.values()) / (n * (n - 1)) return ic
print(indice_coincidence("RIJVS..."))Déchiffrer avec la clé connue
Section intitulée « Déchiffrer avec la clé connue »En ligne, dcode.fr
Section intitulée « En ligne, dcode.fr »https://www.dcode.fr/vigenere-cipher- Coller le texte chiffré dans « Texte chiffré »
- Entrer la clé dans « Clé »
- Cliquer sur « Déchiffrer »
En Python
Section intitulée « En Python »def vigenere_decode(ciphertext, key): key = key.upper() result = [] key_index = 0 for char in ciphertext.upper(): if char.isalpha(): shift = ord(key[key_index % len(key)]) - ord('A') decoded = chr((ord(char) - ord('A') - shift) % 26 + ord('A')) result.append(decoded) key_index += 1 else: result.append(char) return ''.join(result)
print(vigenere_decode("RIJVS", "KEY"))# HELLODéchiffrer sans la clé
Section intitulée « Déchiffrer sans la clé »Si la clé est inconnue, deux informations sont nécessaires : la longueur de la clé, puis les lettres qui la composent.
Trouver la longueur de la clé, test de Kasiski
Section intitulée « Trouver la longueur de la clé, test de Kasiski »Le test de Kasiski cherche des séquences de lettres qui se répètent dans le texte chiffré. La distance entre deux occurrences d’une même séquence est un multiple de la longueur de la clé.
def kasiski(ciphertext, seq_len=3): text = ciphertext.upper().replace(' ', '') positions = {} for i in range(len(text) - seq_len): seq = text[i:i+seq_len] if seq in positions: positions[seq].append(i) else: positions[seq] = [i]
distances = [] for seq, pos in positions.items(): if len(pos) > 1: for i in range(1, len(pos)): distances.append(pos[i] - pos[i-1])
from math import gcd from functools import reduce if distances: pgcd = reduce(gcd, distances) print(f"PGCD des distances : {pgcd}") print(f"Longueur de clé probable : {pgcd} (ou un diviseur)") return distancesTrouver la longueur de la clé, méthode de l’IC
Section intitulée « Trouver la longueur de la clé, méthode de l’IC »Pour chaque longueur candidate L, diviser le texte en L sous-textes (les lettres en positions 0, L, 2L… ; puis 1, L+1, 2L+1… ; etc.). Calculer l’IC de chaque sous-texte. Si L est la bonne longueur, chaque sous-texte est un chiffre de César et son IC se rapproche de celui de la langue source (≈ 0.065 pour l’anglais, ≈ 0.074 pour le français).
def ic_moyen(ciphertext, key_len): text = ciphertext.upper().replace(' ', '') ics = [] for i in range(key_len): sous_texte = text[i::key_len] ics.append(indice_coincidence(sous_texte)) return sum(ics) / len(ics)
for L in range(1, 20): print(f"L={L:2d} IC moyen={ic_moyen(texte_chiffre, L):.4f}")La longueur pour laquelle l’IC moyen est le plus élevé est la longueur de clé probable.
Trouver les lettres de la clé
Section intitulée « Trouver les lettres de la clé »Une fois la longueur L déterminée, chaque sous-texte (lettres en positions 0, L, 2L… etc.) est un César. Analyser la fréquence de chaque sous-texte : la lettre la plus fréquente correspond à la lettre la plus fréquente de la langue source (E en anglais, E ou A en français), ce qui donne le décalage de chaque position de la clé.
def trouver_cle(ciphertext, key_len, lettre_frequente='E'): text = ciphertext.upper().replace(' ', '') key = [] for i in range(key_len): sous_texte = text[i::key_len] freq = Counter(sous_texte) lettre_max = max(freq, key=freq.get) decalage = (ord(lettre_max) - ord(lettre_frequente)) % 26 key.append(chr(decalage + ord('A'))) return ''.join(key)Analyse automatique sur dcode.fr
Section intitulée « Analyse automatique sur dcode.fr »dcode.fr propose une analyse sans clé qui combine Kasiski et analyse fréquentielle :
https://www.dcode.fr/vigenere-cipherColler le texte chiffré, laisser le champ « Clé » vide, et lancer l’analyse automatique. L’outil propose plusieurs longueurs de clé candidates et les clés correspondantes.
Workflow en pratique
Section intitulée « Workflow en pratique »1. Vérifier que le texte est uniquement alphabétique → chiffres ou caractères spéciaux → probablement un autre chiffrement
2. Calculer l'indice de coïncidence → IC proche de la langue source (≈ 0.065–0.074) → substitution monoalphabétique (César) → IC ≈ 0.038–0.055 → polyalphabétique, probable Vigenère
3. Si la clé est connue → dcode.fr ou script Python
4. Si la clé est inconnue → test de Kasiski ou méthode IC pour trouver la longueur → analyse fréquentielle par sous-texte pour trouver les lettres → ou analyse automatique dcode.frÀ retenir
Section intitulée « À retenir »Le chiffre de Vigenère se distingue d’un César par son IC : plus bas que celui d’un texte naturel, plus élevé que celui d’un texte aléatoire. La longueur de la clé se déduit sans la connaître via le test de Kasiski ou l’analyse de l’IC par longueur. Avec la longueur trouvée, chaque sous-texte devient un César standard, déchiffrable par analyse de fréquence.