Attaque par force brute sur le chiffre de César: comment briser le cryptage simple
Apprenez à briser le chiffrement du chiffre César à l’aide d’attaques par force brute. Explique pourquoi le chiffrement est vulnérable avec seulement 25 clés possibles, des approches manuelles et automatisées, une analyse de fréquence et une implémentation Python complète.
Le chiffre César a la particularité d'être l'un des systèmes de cryptage les plus faciles à déchiffrer. Bien qu'il ait bien servi Jules César à une époque où la plupart des gens étaient analphabètes et où le concept de cryptanalyse systématique n'existait pas, le chiffre présente une faiblesse fondamentale qui le rend trivialement vulnérable à une attaque par force brute: il n'y a que 25 clés possibles. Un attaquant n’a pas besoin d’être intelligent, ni de connaissances mathématiques spécialisées, ni même d’un ordinateur. Ils essaient simplement toutes les touches possibles jusqu'à ce que le texte en clair apparaisse.
Cet article explique exactement comment et pourquoi les attaques par force brute fonctionnent contre le chiffre César, parcourt le processus manuellement, vous montre comment l'automatiser avec Python et explore comment l'analyse de fréquence peut améliorer l'attaque pour identifier automatiquement la clé correcte. Nous examinons également les implications plus larges pour la compréhension de la sécurité cryptographique.
Essayez-le vous-même: utilisez notre Décodeur de chiffre César pour expérimenter le décryptage des messages en utilisant différentes valeurs de décalage.
Qu’est-ce qu’une attaque par force brute?
Une attaque par force brute est l’approche la plus simple pour briser le chiffrement: essayez systématiquement toutes les clés possibles jusqu’à ce que vous trouviez celle qui produit un texte clair lisible. Cela ne nécessite aucune connaissance mathématique, aucune reconnaissance de formes et aucune connaissance du texte brut. L’attaquant épuise simplement toutes les possibilités.
La faisabilité d’une attaque par force brute dépend entièrement de la taille de l’espace clé, qui correspond au nombre total de clés possibles. Si l’espace des clés est suffisamment petit pour que chaque clé puisse être testée dans un délai raisonnable, le système de chiffrement est vulnérable à la force brute.
Les algorithmes de chiffrement modernes comme AES-256 ont un espace clé de 2^256, soit environ 1,16 x 10^77 clés possibles. Les tester tous prendrait plus de temps que l’âge de l’univers, même avec les ordinateurs les plus rapides imaginables. C’est ce qui protège le chiffrement moderne contre la force brute.
Le chiffre de César, en revanche, a un espace clé de seulement 25. Ce n’est pas 25 millions ou 25 mille. Il est littéralement vingt-cinq heures. Cela en fait peut-être le chiffrement le plus vulnérable à la force brute jamais utilisé en pratique.
Pourquoi le chiffre de César n'a que 25 clés
Le chiffre de César crypte le texte en décalant chaque lettre vers l'avant d'un nombre fixe de positions dans l'alphabet. La valeur de décalage (ou clé) détermine le nombre de positions déplacées par chaque lettre. L’alphabet anglais étant composé de 26 lettres, il existe 26 valeurs de décalage possibles: de 0 à 25.
Cependant, un décalage de 0 n’est pas du tout un cryptage puisqu’il laisse le texte inchangé. Cela laisse 25 clés significatives:
| Changement | Un devient | Exemple: "HELLO" devient |
|---|---|---|
| 1 | B | IFMMP |
| 2 | C | JGNNQ |
| 3 | D | KHOOR |
| 4 | E | LIPPS |
| 5 | F | MJQQT |
| ... | ... | ... |
| 13 | N | URYYB |
| ... | ... | ... |
| 25 | Z | GDKKN |
Un attaquant qui intercepte un message crypté par César doit tenter au maximum 25 décryptages pour retrouver le texte original. Même le faire à la main ne prend que quelques minutes. Avec un ordinateur, cela prend quelques microsecondes.
Ce minuscule espace clé est la raison fondamentale pour laquelle le chiffre César n’offre pratiquement aucune sécurité. Augmenter la taille de l’alphabet n’aide pas non plus. Même avec un alphabet de 256 caractères, l'espace clé ne serait toujours que de 255, ce qui est négligeable selon toutes les normes.
Procédure pas à pas manuelle de Brute Force
Décomposons manuellement un véritable message crypté pour voir exactement comment le processus fonctionne. Supposons que vous interceptiez le texte chiffré suivant:
Wklv lv d vhfuhw phvvdjh wkdw qr rqh vkrxog eh deoh wr uhdg.
Pour forcer cela, vous essayez systématiquement de décrypter avec chaque valeur de décalage possible. Vous n'avez pas besoin de déchiffrer l'intégralité du message avec chaque clé. Au lieu de cela, vous pouvez examiner uniquement les premiers mots et vérifier s’ils forment un anglais reconnaissable.
Maj 1: Vjku ku c ugetgv oguucig vjcv pq qpg ujqwnf dg cdng vq tgcf.
Ce n'est pas de l'anglais. Continuer.
Maj 2: Uijt jt b tfdsfu nfttbhf uibu op pof tipvme cf bcmf up sfbe.
Toujours pas reconnaissable. Continuer.
Shift 3: Il s'agit d'un message secret que personne ne devrait pouvoir lire.
C'est clairement de l'anglais. La valeur de décalage utilisée pour le chiffrement était de 3, ce qui correspond au décalage de chiffrement classique de César.
En pratique, il est rarement nécessaire d’essayer les 25 touches. Un anglophone courant peut généralement reconnaître un texte lisible dès les premiers caractères, vous pourrez donc identifier le décalage correct après seulement 3 tentatives dans ce cas. En moyenne, vous vous attendez à essayer environ 12 ou 13 clés avant de trouver la bonne.
Force brute automatisée en Python
Bien que la force brute manuelle soit réalisable, son automatisation avec du code est bien plus pratique, en particulier pour les messages plus longs ou lorsque vous devez traiter plusieurs textes chiffrés. Voici un simple script Python qui essaie les 25 équipes:
def caesar_decrypt(ciphertext: str, shift: int) -> str:
"""Decrypt ciphertext by shifting letters backward by the given amount."""
result = []
for char in ciphertext:
if char.isalpha():
base = ord('A') if char.isupper() else ord('a')
decrypted = chr((ord(char) - base - shift) % 26 + base)
result.append(decrypted)
else:
result.append(char)
return ''.join(result)
def brute_force(ciphertext: str) -> list[tuple[int, str]]:
"""Try all 25 possible shifts and return the results."""
results = []
for shift in range(1, 26):
decrypted = caesar_decrypt(ciphertext, shift)
results.append((shift, decrypted))
return results
# Example usage
ciphertext = "Wklv lv d vhfuhw phvvdjh wkdw qr rqh vkrxog eh deoh wr uhdg."
print("Ciphertext:", ciphertext)
print("\n=== All 25 Possible Decryptions ===\n")
for shift, plaintext in brute_force(ciphertext):
print(f"Shift {shift:2d}: {plaintext}")
La sortie affiche les 25 décryptages possibles, et le décalage 3 produit un anglais lisible:
Ciphertext: Wklv lv d vhfuhw phvvdjh wkdw qr rqh vkrxog eh deoh wr uhdg.
=== All 25 Possible Decryptions ===
Shift 1: Vjku ku c ugetgv oguucig vjcv pq qpg ujqwnf dg cdng vq tgcf.
Shift 2: Uijt jt b tfdsfu nfttbhf uibu op pof tipvme cf bcmf up sfbe.
Shift 3: This is a secret message that no one should be able to read.
Shift 4: Sghr hr z rdbqds ldrrzfd sgzs mn nmd rgntkc ad zkmd sn qdzc.
...
Un humain peut parcourir cette liste et repérer immédiatement la bonne réponse. Mais que se passe-t-il si vous souhaitez que l’ordinateur l’identifie automatiquement?
Amélioration de l'analyse de fréquence
L'analyse de fréquence améliore considérablement les attaques par force brute en permettant à l'ordinateur d'identifier automatiquement le décryptage correct le plus probable. La technique repose sur le fait que dans tout texte anglais suffisamment long, certaines lettres apparaissent plus fréquemment que d’autres. La lettre E est la plus courante (environ 12,7 % de toutes les lettres), suivie de T (9,1 %), A (8,2 %), O (7,5 %), I (7,0 %), N (6,7 %) et S (6,3 %).
Lorsque vous déchiffrez un chiffre de César avec la mauvaise clé, le texte résultant comporte des fréquences de lettres qui ne correspondent pas à l'anglais. Lorsque vous déchiffrez avec la bonne clé, les fréquences s'alignent étroitement sur la distribution anglaise attendue.
Voici une implémentation Python qui note chaque résultat de force brute à l'aide d'une analyse de fréquence et identifie automatiquement le décryptage correct le plus probable:
# English letter frequencies (percentage)
ENGLISH_FREQ = {
'a': 8.167, 'b': 1.492, 'c': 2.782, 'd': 4.253, 'e': 12.702,
'f': 2.228, 'g': 2.015, 'h': 6.094, 'i': 6.966, 'j': 0.153,
'k': 0.772, 'l': 4.025, 'm': 2.406, 'n': 6.749, 'o': 7.507,
'p': 1.929, 'q': 0.095, 'r': 5.987, 's': 6.327, 't': 9.056,
'u': 2.758, 'v': 0.978, 'w': 2.360, 'x': 0.150, 'y': 1.974,
'z': 0.074,
}
def score_text(text: str) -> float:
"""
Score text based on how closely its letter frequencies
match expected English frequencies. Higher is better.
Uses chi-squared-like comparison.
"""
text_lower = text.lower()
letter_count = sum(1 for c in text_lower if c.isalpha())
if letter_count == 0:
return float('inf') # Cannot score text with no letters
# Count actual frequencies
observed = {}
for c in text_lower:
if c.isalpha():
observed[c] = observed.get(c, 0) + 1
# Calculate chi-squared statistic (lower = better match)
chi_squared = 0.0
for letter, expected_pct in ENGLISH_FREQ.items():
expected_count = (expected_pct / 100.0) * letter_count
actual_count = observed.get(letter, 0)
if expected_count > 0:
chi_squared += ((actual_count - expected_count) ** 2) / expected_count
return chi_squared
def smart_brute_force(ciphertext: str) -> tuple[int, str]:
"""
Brute force attack with automatic key detection
using frequency analysis scoring.
"""
best_shift = 0
best_score = float('inf')
best_text = ciphertext
for shift in range(1, 26):
decrypted = caesar_decrypt(ciphertext, shift)
score = score_text(decrypted)
if score < best_score:
best_score = score
best_shift = shift
best_text = decrypted
return best_shift, best_text
# Example
ciphertext = "Wklv lv d vhfuhw phvvdjh wkdw qr rqh vkrxog eh deoh wr uhdg."
shift, plaintext = smart_brute_force(ciphertext)
print(f"Detected shift: {shift}")
print(f"Decrypted text: {plaintext}")
Sortie:
Detected shift: 3
Decrypted text: This is a secret message that no one should be able to read.
La statistique du chi carré mesure la différence entre les fréquences de lettres observées et les fréquences anglaises attendues. Une valeur du chi carré inférieure signifie une correspondance plus étroite. Le décryptage avec le score le plus bas est la réponse correcte la plus probable.
Cette approche fonctionne de manière fiable pour les textes chiffrés comportant plus de 50 caractères environ. Pour les messages très courts (moins de 20 caractères), il se peut qu'il n'y ait pas suffisamment de lettres pour produire des statistiques de fréquence significatives, et la notation automatisée peut donner des résultats incorrects. Dans ces cas-là, l’inspection humaine du résultat de la force brute est plus fiable.
Un outil d'attaque complet
Le script suivant combine le tout dans un outil d'attaque pratique avec une sortie formatée:
def caesar_decrypt(ciphertext: str, shift: int) -> str:
result = []
for char in ciphertext:
if char.isalpha():
base = ord('A') if char.isupper() else ord('a')
result.append(chr((ord(char) - base - shift) % 26 + base))
else:
result.append(char)
return ''.join(result)
ENGLISH_FREQ = {
'a': 8.167, 'b': 1.492, 'c': 2.782, 'd': 4.253, 'e': 12.702,
'f': 2.228, 'g': 2.015, 'h': 6.094, 'i': 6.966, 'j': 0.153,
'k': 0.772, 'l': 4.025, 'm': 2.406, 'n': 6.749, 'o': 7.507,
'p': 1.929, 'q': 0.095, 'r': 5.987, 's': 6.327, 't': 9.056,
'u': 2.758, 'v': 0.978, 'w': 2.360, 'x': 0.150, 'y': 1.974,
'z': 0.074,
}
def score_text(text: str) -> float:
text_lower = text.lower()
letter_count = sum(1 for c in text_lower if c.isalpha())
if letter_count == 0:
return float('inf')
observed = {}
for c in text_lower:
if c.isalpha():
observed[c] = observed.get(c, 0) + 1
chi_sq = 0.0
for letter, expected_pct in ENGLISH_FREQ.items():
expected = (expected_pct / 100.0) * letter_count
actual = observed.get(letter, 0)
if expected > 0:
chi_sq += ((actual - expected) ** 2) / expected
return chi_sq
def attack(ciphertext: str) -> None:
print(f"Ciphertext: {ciphertext}")
print(f"Length: {len(ciphertext)} characters")
print(f"Letters: {sum(1 for c in ciphertext if c.isalpha())}")
print()
results = []
for shift in range(1, 26):
decrypted = caesar_decrypt(ciphertext, shift)
score = score_text(decrypted)
results.append((shift, decrypted, score))
# Sort by score (lowest chi-squared = best match)
results.sort(key=lambda x: x[2])
print("=== Top 5 Most Likely Decryptions ===\n")
for i, (shift, text, score) in enumerate(results[:5]):
marker = " <-- BEST MATCH" if i == 0 else ""
print(f" Shift {shift:2d} (score: {score:8.2f}): {text}{marker}")
print("\n=== All 25 Decryptions ===\n")
# Show in shift order
results.sort(key=lambda x: x[0])
for shift, text, score in results:
print(f" Shift {shift:2d}: {text}")
if __name__ == "__main__":
import sys
if len(sys.argv) > 1:
ciphertext = ' '.join(sys.argv[1:])
else:
ciphertext = input("Enter ciphertext: ")
print()
attack(ciphertext)
Utilisation:
python3 caesar_attack.py "Wklv lv d vhfuhw phvvdjh"
# Or interactively:
python3 caesar_attack.py
Enter ciphertext: Ymj vznhp gwtbs ktc ozrux tajw ymj qfed itl.
Pourquoi Brute Force fonctionne si bien contre le chiffre de César
Plusieurs facteurs se combinent pour rendre le chiffre César exceptionnellement vulnérable à la force brute:
Petit espace pour les clés: Avec seulement 25 clés possibles, même un enfant peut toutes les essayer à la main en moins de dix minutes. Un ordinateur peut tester les 25 en microsecondes.
Clé égale algorithme: Dans le chiffre César, connaître la clé (valeur de décalage) vous indique immédiatement l'intégralité de l'algorithme de cryptage. Il n’y a pas de complexité supplémentaire, pas de calendrier clé, pas de cycles de transformation. Un seul numéro débloque tout.
Substitution déterministe: chaque lettre correspond toujours exactement à une autre lettre pour une clé donnée. La lettre E devient toujours H avec un décalage de 3, quel que soit l'endroit où elle apparaît dans le message. Ce déterminisme est ce qui rend l’analyse fréquentielle si puissante.
Pas de diffusion: La modification d'une lettre du texte en clair modifie exactement une lettre du texte chiffré. Dans les chiffrements modernes, la modification d'un bit d'entrée modifie environ la moitié des bits de sortie (l'effet d'avalanche). Le chiffre César n’a aucun effet d’avalanche.
Structure préservée: les espaces, la ponctuation et les limites des mots sont conservés dans le texte chiffré. Cela donne à l'attaquant d'énormes quantités d'informations structurelles sur le texte en clair. Un attaquant peut immédiatement voir la longueur des mots, la structure des phrases et le formatage des paragraphes.
Quand la force brute ne suffit pas
Bien que la force brute brise de manière triviale le chiffre de César, il est utile de comprendre quand cette approche échoue, car ces limitations expliquent pourquoi des attaques plus sophistiquées existent.
Chiffres polyalphabétiques: Le chiffre de Vigenère utilise un décalage différent pour chaque position dans le texte, en fonction d'un mot-clé. Avec un mot-clé de longueur k, l'espace clé effectif est de 26 ^ k, qui croît de façon exponentielle. Un mot-clé de 10 lettres produit 26 ^ 10 (environ 141 000 milliards) de clés possibles, bien au-delà de la force brute pratique. Différentes techniques cryptanalytiques comme l'examen de Kasiski et le test de Friedman sont nécessaires.
Type de chiffrement inconnu: la force brute suppose que vous connaissez l'algorithme de chiffrement et que vous recherchez uniquement la clé. Si vous interceptez un message et ne savez pas quel chiffre a été utilisé, vous avez besoin d'une analyse supplémentaire avant que la force brute ne soit applicable.
Texte brut non anglais: la notation de l'analyse de fréquence suppose un texte anglais. Si le message d'origine est dans une autre langue, vous avez besoin de tableaux de fréquences pour cette langue. Si le message n’est pas du tout en langage naturel (données aléatoires, données compressées ou autre couche de cryptage), l’analyse de fréquence ne permettra pas d’identifier le décryptage correct.
Variantes César modifiées: Certaines variantes utilisent un alphabet non standard, chiffrent des chiffres et des symboles ou appliquent des transformations supplémentaires. Bien qu’encore fondamentalement faibles, ces variantes peuvent nécessiter des approches de force brute ajustées.
Perspective historique sur la force brute
Le concept consistant à essayer systématiquement toutes les clés possibles est aussi ancien que la cryptographie elle-même. Le mathématicien arabe Al-Kindi a décrit l'analyse des fréquences au IXe siècle dans son ouvrage « Un manuscrit sur le déchiffrement des messages cryptographiques », qui est considéré comme la première description connue de la cryptanalyse.
Cependant, il a fallu attendre la mécanisation de la cryptographie au XXe siècle pour que la force brute soit devenue un concept formel. Pendant la Seconde Guerre mondiale, les décrypteurs alliés de Bletchley Park ont utilisé les premières machines informatiques (la Bombe, conçue par Alan Turing, et plus tard le Colossus) pour effectuer des recherches par force brute sur les espaces clés des chiffres Enigma et Lorenz. Ces machines pouvaient tester des milliers de combinaisons de touches par seconde, ce qui était révolutionnaire à l'époque.
Aujourd’hui, les ordinateurs modernes peuvent tester des milliards de clés de chiffrement simples par seconde. Face à un chiffre doté de seulement 25 clés, même le microcontrôleur intégré le plus lent peut effectuer une recherche exhaustive instantanément. Cette progression historique, du calcul manuel aux ordinateurs mécaniques en passant par les ordinateurs électroniques, a rendu le minuscule espace clé du chiffre César de plus en plus absurde en tant que mesure de sécurité.
Se défendre contre la force brute
Comprendre les attaques par force brute permet d'expliquer pourquoi le chiffrement moderne utilise de grands espaces de clés:
- AES-128: 2^128 clés possibles (environ 3,4 x 10^38). Avec un milliard de clés par seconde, une recherche exhaustive prendrait environ 10 à 22 ans.
- AES-256: 2^256 clés possibles (environ 1,16 x 10^77). Il y a plus de clés possibles qu’il n’y a d’atomes dans l’univers observable.
- RSA-2048: la sécurité vient de la difficulté de prendre en compte de grands nombres, pas seulement de la taille de l'espace clé, mais la sécurité efficace équivaut à environ 2^112 opérations par force brute.
La leçon à tirer du forçage brutal du chiffre César est claire: la sécurité du chiffrement dépend de la nécessité de rendre la recherche exhaustive par clé impossible sur le plan informatique. Tout système dans lequel toutes les clés peuvent être testées dans un délai raisonnable n’offre aucune réelle sécurité, quelle que soit la manière dont fonctionne l’algorithme de chiffrement lui-même.
Résumé
Le chiffre César est particulièrement vulnérable à la force brute car son espace clé de 25 est négligeable. Une attaque manuelle prend quelques minutes. Une attaque automatisée prend quelques microsecondes. L'ajout d'une analyse de fréquence permet à un ordinateur d'identifier automatiquement la bonne clé sans inspection humaine.
Comprendre comment la force brute brise le chiffre de César fournit un contexte essentiel pour comprendre pourquoi les systèmes de chiffrement modernes utilisent des espaces de clés extrêmement grands. La progression de 25 clés possibles à 2 ^ 256 clés possibles représente la réponse de la communauté cryptographique à la leçon fondamentale que le chiffre de César enseigne: si vous pouvez essayer chaque clé, le chiffre est cassé.
Explorez davantage: découvrez l'Algorithme de chiffrement César pour comprendre les mathématiques derrière le cryptage, ou essayez de déchiffrer vous-même les chiffrements avec notre Décodeur de chiffrement César.