Chiffrement de Vigenère en Java
Le chiffre de Vigenère est un algorithme de chiffrement polyalphabétique inventé au XVIe siècle. Il repose sur une clé répétée qui décale chaque lettre du message clair. Longtemps considéré indéchiffrable ("le chiffre indéchiffrable"), il est trivialement cassable aujourd'hui — c'est néanmoins un exercice pédagogique parfait en Java.
Principe
Pour chiffrer la lettre m avec la lettre-clé k :
chiffré = ((m - 'A') + (k - 'A')) mod 26 + 'A'
Pour déchiffrer :
clair = ((c - 'A') - (k - 'A') + 26) mod 26 + 'A'
Exemple avec la clé LEMON :
Texte : ATTACKATDAWN
Clé : LEMONLEMONLE
Chiffré: LXFOPVEFRNHR
Implémentation complète
public class Vigenere {
public static String chiffrer(String message, String cle) {
return transformer(message, cle, true);
}
public static String dechiffrer(String message, String cle) {
return transformer(message, cle, false);
}
private static String transformer(String texte, String cle, boolean chiffrer) {
if (cle == null || cle.isEmpty()) {
throw new IllegalArgumentException("La clé ne peut pas être vide");
}
String texteMaj = texte.toUpperCase();
String cleMaj = cle.toUpperCase();
StringBuilder sortie = new StringBuilder();
int indexCle = 0;
for (char c : texteMaj.toCharArray()) {
if (c < 'A' || c > 'Z') {
sortie.append(c); // on ne chiffre pas ponctuation et espaces
continue;
}
int decalage = cleMaj.charAt(indexCle % cleMaj.length()) - 'A';
if (!chiffrer) decalage = -decalage;
int lettre = ((c - 'A' + decalage) % 26 + 26) % 26;
sortie.append((char) ('A' + lettre));
indexCle++;
}
return sortie.toString();
}
public static void main(String[] args) {
String message = "ATTAQUEZ A L'AUBE";
String cle = "LEMON";
String code = chiffrer(message, cle);
String clair = dechiffrer(code, cle);
System.out.println("Chiffré : " + code);
System.out.println("Clair : " + clair);
}
}
Points clés de l'implémentation :
- L'index de la clé n'avance que sur les lettres chiffrées, pas sur les espaces ou ponctuation, sinon la synchronisation casse.
- Le
((x % 26) + 26) % 26garantit un résultat positif même pour un décalage négatif. - On passe tout en majuscules pour simplifier — la préservation de la casse se traite à part.
Préserver la casse du texte clair
private static String transformerAvecCasse(String texte, String cle, boolean chiffrer) {
StringBuilder sortie = new StringBuilder();
int indexCle = 0;
String cleMaj = cle.toUpperCase();
for (char c : texte.toCharArray()) {
if (Character.isLetter(c)) {
char base = Character.isUpperCase(c) ? 'A' : 'a';
int decalage = cleMaj.charAt(indexCle % cleMaj.length()) - 'A';
if (!chiffrer) decalage = -decalage;
int lettre = ((c - base + decalage) % 26 + 26) % 26;
sortie.append((char) (base + lettre));
indexCle++;
} else {
sortie.append(c);
}
}
return sortie.toString();
}
Gérer les caractères accentués
Le Vigenère opère sur les 26 lettres latines. Les caractères accentués (é, à, ç) doivent être normalisés avant chiffrement :
import java.text.Normalizer;
public static String normaliser(String s) {
return Normalizer.normalize(s, Normalizer.Form.NFD)
.replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
}
// "Café" → "Cafe"
La normalisation fait perdre les accents à la restitution : acceptable pour un exercice pédagogique, inacceptable pour un vrai outil de chiffrement.
Pourquoi Vigenère est cassé
Dès le XIXe siècle, le test de Kasiski et l'analyse de fréquence ont révélé la faille : si la clé se répète, les mêmes séquences de lettres-clé chiffrent les mêmes motifs du clair. En comparant les distances entre motifs répétés du texte chiffré, on devine la longueur de la clé ; puis une analyse de fréquence classique la retrouve.
Un script moderne casse un Vigenère de clé < 20 sur un texte français de 500 caractères en moins d'une seconde. Ne jamais utiliser Vigenère en production.
Pour un vrai chiffrement en Java
Utilisez les APIs standard :
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
KeyGenerator gen = KeyGenerator.getInstance("AES");
gen.init(256);
SecretKey key = gen.generateKey();
Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
c.init(Cipher.ENCRYPT_MODE, key);
byte[] chiffre = c.doFinal("message".getBytes("UTF-8"));
AES en mode GCM est la référence actuelle pour le chiffrement symétrique : rapide, authentifié, et analysé par la communauté cryptographique depuis vingt ans.
Mais pour apprendre les bases de la cryptographie, Vigenère reste un passage obligé — une centaine de lignes de code qui racontent trois cents ans d'histoire.