I. De César à Vigenère

I-A. Le cryptage de César

On appelle cryptage de Jules César un système de cryptage par substitution monoalphabétique. Cela signifie tout simplement que, pour chaque caractère à rendre 'secret', on lui substitue un et un seul autre caractère. S'il porte le nom de Jules César, c'est parce qu'il aurait utilisé ce genre de système. Il s'agit donc d'une technique qui a prouvé son efficacité, mais qui a maintenant plus de 2000 ans. Très simple donc. Hélas, il est également très facile à cracker car, une fois un caractère trouvé, il devient très facile de retrouver tous les autres.

Voici un exemple très simple à comprendre : imaginons que vous souhaitiez crypter 'DEVELOPPEZ.COM' suivant le système de cryptage par substitution en prenant pour chaque caractère, le caractère qui le précède dans la table ASCII, qu'aurions nous ? Il nous faut avoir un petit aperçu de la table ASCII... en voici un extrait pour notre codepage à nous :

=32 ! =33 " =34 # =35 $ =36 % =37 & =38 ' =39 ( =40 ) =41 * =42 + =43 , =44 - =45 . =46 / =47
0 =48 1 =49 2 =50 3 =51 4 =52 5 =53 6 =54 7 =55 8 =56 9 =57 : =58 ; =59 < =60 = =61 > =62 ? =63
@ =64 A =65 B =66 C =67 D =68 E =69 F =70 G =71 H =72 I =73 J =74 K =75 L =76 M =77 N =78 O =79
P =80 Q =81 R =82 S =83 T =84 U =85 V =86 W =87 X =88 Y =89 Z =90 [ =91 \ =92 ] =93 ^ =94 _ =95
` =96 a =97 b =98 c =99 d =100 e =101 f =102 g =103 h =104 i =105 j =106 k =107 l =108 m =109 n =110 o =111
p =112 q =113 r =114 s =115 t =116 u =117 v =118 w =119 x =120 y =121 z =122 { =123 | =124 } =125 ~ =126  =127
=128 \x81 =129 =130 ƒ =131 =132 =133 =134 =135 ˆ =136 =137 Š =138 =139 Œ =140 \x8D =141 Ž =142 \x8F =143
\x90 =144 =145 ' =146 =147 =148 =149 - =150 =151 ˜ =152 =153 š =154 =155 œ =156 \x9D =157 ž =158 Ÿ =159
  =160 ¡ =161 ¢ =162 £ =163 ¤ =164 ¥ =165 ¦ =166 § =167 ¨ =168 © =169 ª =170 « =171 ¬ =172 ­ =173 ® =174 ¯ =175
° =176 ± =177 ² =178 ³ =179 ´ =180 µ =181 =182 · =183 ¸ =184 ¹ =185 º =186 » =187 ¼ =188 ½ =189 ¾ =190 ¿ =191
À =192 Á =193 Â =194 Ã =195 Ä =196 Å =197 Æ =198 Ç =199 È =200 É =201 Ê =202 Ë =203 Ì =204 Í =205 Î =206 Ï =207
Ð =208 Ñ =209 Ò =210 Ó =211 Ô =212 Õ =213 Ö =214 × =215 Ø =216 Ù =217 Ú =218 Û =219 Ü =220 Ý =221 Þ =222 ß =223
à =224 á =225 â =226 ã =227 ä =228 å =229 æ =230 ç =231 è =232 é =233 ê =234 ë =235 ì =236 í =237 î =238 ï =239
ð =240 ñ =241 ò =242 ó =243 ô =244 õ =245 ö =246 ÷ =247 ø =248 ù =249 ú =250 û =251 ü =252 ý =253 þ =254 ÿ =255

Alors ? Vous avez trouvé ce que donnerait DEVELOPPEZ.COM ? Oui, c'est ça ! CDUDKNOODY-BNL

Maintenant, il ne reste plus qu'à déterminer un décalage, voire même un ordre, et le tour est joué. Si ce système de cryptage a pu fonctionner au temps de César, il se fait craquer presque instantanément maintenant. Il suffit de regarder le nombre de jeux de lettres qu'on peut trouver dans les magazines à ce sujet ! Nous allons donc tenter de faire un tout petit peu mieux.

I-B. Le cryptage de Vigenère

Le cryptage de Vigenère reprend le même concept de base : Nous avons une suite de caractère à traduire, et nous avons également une chaîne de caractères de référence. Mais Vigenère va plus loin en ce que, la chaîne de référence peut très bien être une phrase quelconque, et que, de plus, il crée des associations de lettre. En fait, on ne peut plus parler de substitution monoalphabétique...

Illustrons ceci par l'exemple : Si je devais crypter DEVELOPPEZ.COM et que ma phrase de référence était Coucou, je devrai crypter la résultante d'une série d'associations de chaque lettre ainsi :

D+C E+o V+u E+c L+o O+u P+C P+o E+u Z+c .+o C+u O+C M+o

Ce qui, en valeurs ASCI nous donne :

68+67 69+79 86+85 69+67 76+79 79+85 80+67 80+79 69+85 90+67 46+79 67+85 79+67 77+79

Une fois les additions faites, nous arrivons à :

135 148 171 136 155 164 147 159 154 157 125 152 146 156 Voici donc la suite des caractères ASCII qui vont donner la chaîne crypter en résultat.

Voilà, lorsque nous utilisons la méthode de Vigenère pour crypter DEVELOPPEZ.COM à partir de la chaîne Coucou, nous obtenons donc ‡”«ˆ›¤“Ÿš\x9D}˜’œ

Le gros avantage de cette méthode, c'est qu'à un caractère à crypter, il peut y avoir plusieurs caractères associés, comme nous l'avons vu dans notre exemple. Mais sa faille est que le cycle peut être trouvé assez facilement. Une solution consiste à générer une chaîne de cryptage (une clef) qui soit très longue. Si possible aussi longue que le texte à crypter. Ce qui dans l'absolu est impossible, puisque la longueur de la chaîne est inconnue au départ.

II. Fabriquons notre petite fonction

Maintenant que nous avons vu les principes de base, nous allons pouvoir passer à la réalisation. Puisque nous avons vu que nous avions besoin d'une chaîne très aléatoire, pour compliquer la découverte du cycle, et également suffisamment longue, je vous propose de créer une constante telle :

 
Sélectionnez
    Const CLEF              As String = "nbvfdszé""'(-è_ijhgfcKLKjhgyuilM^+)àçiu-('32azsDRtvBhujkoç_è6tre""zsXWqazerfcx<;:<?"

Ce sera notre clé de cryptage. Mais vous pouvez inventer la votre. Pensez simplement qu'en VBA, pour inscrire le caractère 34 (") dans une chaîne de caractères, vous devez le doubler.

Pensez aussi que vous risquez deux choses qui pourraient faire planter votre programme
  1. L'addition des 2 codes ASCII risque de dépasser la valeur 255, ce qui n'est pas acceptable, les valeurs de la table ASCII étant comprises entre 0 et 255. un moyen de passer outre cette limite sera d'utiliser le modulo (reste d'une division entière) par 256
  2. La longueur de la chaîne à crypter pourrait être plus longue que votre clé, ce qui implique de retourner au début de la clé à chaque fois qu'on est arrivé à la fin. Encore une fois, le modulo par la longueur de la chaîne devrait nous permettre de nous en sortir.

Enfin, un point qui pourrait être amusant serait de crypter la chaîne à crypter plusieurs fois de suite, histoire de compliquer un peu la tâche de ceux qui veulent décrypter.

Trucs de codage

Vous ne le saviez peut-être pas, mais, lorsque vous écrivez ceci :

 
Sélectionnez
Dim s as String
s="A"
s=s & "B"

Vous utilisez énormément de ressources système (enfin ... tout est relatif) car, il y a création de la variable s pour stocker "A", puis pour ajouter le "B", il va falloir que le système recrée une variable contenant les 2 caractères ; alors que si on avait écrit ceci :

 
Sélectionnez
s="xx"
mid(s,1,1)="A"
mid(s,2,1)="B"

nous utilisons toujours la même variable, et nous la modifions au fur et à mesure qu'on modifie la position d'un caractère. Cette deuxième écriture demande donc moins de traitements au procésseur et est donc plus rapide au niveau traitement. C'est donc la solution que j'ai favorisé dans le code de la fonction.

III. Le code complet

Allez .. je ne vous fais pas languir plus longtemps ... voici le code de la fonction, code commenté. Amusez-vous bien !

 
Sélectionnez
Function Crypter(ByVal chaîneACrypter As String)
'---------------------------------------------------------------------------------------
' Procedure : Crypter
' Créée le  : lundi 18 juil 2005 18:51
' Auteur    : Maxence HUBICHE
' Site      : http://mhubiche.developpez.com
' Objet     : Crypter la chaîne chaîneACrypter en fonction d'une clef et de la méthode
'               de Vigenère
'---------------------------------------------------------------------------------------
'
    Dim sLettres    As String
    Dim lCompteur   As Long
    Dim lLongueur   As Long
    Dim lBoucle     As Long
    
    'Définition des constantes utiles pour la fonction (Clé et nombre d'itérations de la fonction maximum)
    Const CLEF              As String = "nbvfdszé""'(-è_ijhgfcKLKjhgyuilM^+)àçiu-('32azsDRtvBhujkoç_è6tre""zsXWqazerfcx<;:<?"
    Const NBROTATIONSMAX    As Long = 13
    
    'Définition de la longueur de la chaîne à crypter et de la chaîne de résultat
    lLongueur = Len(chaîneACrypter)
    sLettres = String(lLongueur, Chr(0))
    
    'Boucler en fonction du nombre de rotations attendues
    For lBoucle = 1 To NBROTATIONSMAX 
        'boucler pour chaque caractère de la chaîne initiale
        For lCompteur = 1 To lLongueur
            'Remplacer le caractère de la chaîne à crypter par le caractère correspondant à
            '   le reste de
            '       la valeur ascii du caractère à crypter
            '       plus
            '       la valeur ascii du caractère correspondant dans la clé, multiplié par la longueur de la clé
            '   quand on le divise par 256
            Mid(sLettres, lCompteur, 1) = Chr((Asc(Mid(chaîneACrypter, lCompteur, 1)) + _
					(Asc(Mid(CLEF, (lCompteur Mod Len(CLEF)) + 1, 1)) * lLongueur)) Mod 256)
        'recommencer
        Next
        'réaffecter la chaîne à crypter par le résultat trouvé pour pouvoir recommencer une itération
        chaîneACrypter = sLettres
    'Nouvelle itération
    Next
    'Renvoyer le résultat final
    Crypter = sLettres
End Function

Allez, si vous avez compris, je vous laisse découvrir la fonction qui permettra le décryptage ! Amusez-vous bien !