CryptAfinity est un logiciel libre permettant de déchiffrer des texte obfusqués par des systèmes Afines ou l'algorithme de Vigenère. Il possède les caractéristiques suivantes :
CryptAfinity a été entièrement réalisé par Glenn ROLLAND <glenux@fr.st> à l'occasion de travaux pratiques du cours de système du Master 2 Ingénierie Informatique - Systèmes, Réseaux et Internet.
CryptAfinity nécessite les bibliothèques de fonctions suivantes (dans leur version de développement si compilez le programme vous-même):
Il vous suffit de taper (en tant qu'administrateur) les commandes suivantes pour installer le nécessaire:
# apt-get install libglib-2.0-dev
Il est nécessaire d'avoir installé les autotools (automake, autoconf...) dans leur dernière version. À partir de là, il suffit de taper les commandes suivantes dans un terminal :
# sudo fink install glib2-dev
Vous pouvez télécharger la dernière archive des sources, ou bien directement la version la plus récente du projet sur le dépôt Subversion du projet.
Elle est disponible à l'adresse :
http://glenux2.free.fr/pub/projets/CryptAfinity/archives/Afin d'obtenir les sources les plus à jour, vous pouvez utiliser le logiciel de contrôle de sources Subversion
$ svn checkout http://repository.glenux.ath.cx/svn/CryptAfinity/
Il n'y a pas de mot de passe, il suffit donc de presser la touche "Entrée" pour l'utilisateur "anonymous", si ce dernier vous est demandé.
Commencez par décompressez l'archive.
$ tar -xzvf CryptAfinity-0.1.tar.gz
Rendez vous ensuite dans le dossier qui vient d'être créé lors de la décompression.
$ cd CryptAfinity-0.2
Puis lancez l'auto-configuration du logiciel, puis la compilation.
$ ./autogen
$ ./configure
$ make
Le programme sous forme binaire se trouvera alors dans le sous-dossier src/tools/, sous le nom break_afinity
CryptAfinity nécessite de nombreux paramètres, avec la syntaxe suivante:
Usage:
break_afinity -a <fichier> -e <float> -f
<float> -p <fichier> -t
<fichier> -m
Où les paramètres sont les suivants:
-a, --alphabet <file> | Fichier contenant les lettres de l'alphabet, dans l'ordre. |
-e, --epsilon <float> |
Tolerance pour le test des clefs. |
-f, --frequencies <float> | Proportion moyenne que représentent les 9 lettres "prioritaires" dans le texte clair. |
-k, --keylength <int> | Taille de la clef maximul (obsolète) |
-p, --priorities <file> | Lettres ordonnées par fréquence décroissante d'apparition dans le texte clair. |
-t, --text <file> | Fichier contenant le texte chiffré. |
-m, --mode <a|v> | Selection du mode "Afine" ou "Vigenère" |
Vous pouvez trouver la documentation du code de CryptAfinity dans le dossier doc/html de l'application, ou en suivant ce lien.
On génère l'espace des clefs possibles pour l'alphabet donné en entrée:
int alpha_size; //taille de l'alphabet
std::list<int> orb; // nombre premiers avec alpha_size
MathTools mt; // bibliotheque d'outils mathématiques
std::list<KeyAfine> keyList;
std::list<int>::iterator orbIt;
for (i=1; i<alpha_size; i++){
if (mt.pgcd(i, alpha_size) == 1) {
orb.push_back(i);
}
}
// 1 - générer l'espace des 312 clefs
for (orbIt = orb.begin(); orbIt != orb.end(); orbIt++){
KeyAfine key;
key.setCoefA((*orbIt));
for (i=0; i<alpha_size; i++){
key.setCoefB(i);
keyList.push_back(key);
}
}
Puis on fait une attaque par analyse de fréquence sur les textes obtenus par "décodage" du texte chiffré avec les clefs essayées.
float frequencies; // fréquence cumulée des 9 lettres les plus présentes
float epsilon; // marge d'erreur
std::list<KeyAfine>::iterator kLIt;
for (kLIt = keyList.begin(); kLIt != keyList.end(); kLIt++){
float score = 0;
printf("Trying key %s\n", (*kLIt).toString().c_str());
plainText = codec.decode(cypherText, *kLIt);
plainText.setAlphabet(this->_config.getAlphabet());
for (int i=0; i<9; i++){
score += plainText.getCountOf(prio_conf[i]);
}
score = score / plainText.size();
if (fabs(score - frequencies) < epsilon){
printf("KEY = %s\n",(*kLIt).toString().c_str());
printf("PLAIN TEXT(%f) = %s\n", fabs(score-frequencies),
plainText.toAlphabet().c_str());
}
}