Bonjour à tous,

Il y a quelques jours, j'ai développé un algorithme de chiffrement symétrique, simpliste mais efficace, et je viens vous le présenter.

Le Pyramidal Encryption Standard est basé sur le principe des nombres pyramidaux.

Ses forces :
  • Longueur de clef indéfinie * (plages à brute-forcer, de 0 à l'infini)
  • Basé sur l'encodage de caractères (défini par l'utilisateur)
  • Pas de dictionnaire
  • Pas de marqueurs
  • Longueur de la chaine chiffrée égale à celle de la chaîne de départ


Ses faiblesses :
  • Gourmand en ressources, selon la longueur de la clef et de la chaîne à (dé)chiffrer


* Personnellement, je recommande longueur de la chaîne à chiffrer + 1 (par défaut), afin d'assurer, au minimum, un double écrasement de toutes les valeurs.

Le concept, par étapes :

Prenons donc un exemple de nombres.
Pour chaque rang, la valeur inscrite dans une colonne est augmentée de la valeur de inscrite, au rang précédent, dans la colonne précédente.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
 
1   3   5   7   9
1   4   8  12  16
1   5  12  20  28
Appliquons cela à une chaîne de caractères :
C'est assez simple, dans un encodage défini, à tout caractère correspond une valeur numérique.

Pour cet exemple, tout comme pour la démo, j'ai choisi l'UTF-8, mais ce principe est applicable à n'importe quel encodage.

Prenons la chaine une chaîne anodine :
Convertissons-la en codes numériques :
Ensuite, appliquons le principe des nombre pyramidaux :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
84 185 221 236 217
84 269 406 457 453
84 353 675 863 910
Afin de pouvoir représenter ces nombres sous forme de caractères (chaîne chiffrée), toute valeur au moins égale à au nombre de caractères défini par l'encodage se verra diminuée de ce nombre. Dans le cas de l'UTF-8, il y a 65536 caractères.

Donc, par exemple :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
 
charCode=67536
si (charCode >= 65536)
alors charCode = charCode - 65536 // 2000
La clef :
Sans une clef, vous l'aurez remarqué, il est assez facile de prédire le message original. De plus, le premier caractère est toujours en clair.

Prenons donc une clef anodine :
Côté script, afin de renforcer le chiffrage, tant que la longueur de cette clef est inférieure à la longueur du message, nous allons concaténer cette clef à elle-même, dans le cas présent, cela donnera :
Convertissons-la en codes numériques :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
109 100 112 109 100 112

Introduction de la clef :
Pour chaque code de la clef, nous allons créer un rang à la suite de codes de notre chaîne à chiffrer, où nous allons additionner ce code à la valeur de la 1ère colonne de ce rang et y appliquer un XOR code de la clef.

Ce qui donne :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
172  212  176  129  180
372  484  480  341  337
404  808  948  837  726
620 1233 1713 1684 1654
692 1881 3046 3361 3438
852 2685 4943 6519 6911
Au lieu de :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
84 185 221 236 217
84 269 406 457 453
84 353 675 863 910
Et, reconverti en caractères (en UTF-8) :
Voilà, qu'en pensez-vous?


N.B. : La démo étant en JavaScript, on est un peu limités au niveau de la récursivité, donc n'abusez pas trop sur vos longueurs de mot de passe/texte à (dé)chiffrer.

EDIT : Correction du bug lié à une clef trop courte (oubli d'un passage de paramètre)

Ajout d'un XOR placé de manière à empêcher l'altération des données.