[C] Cryptographie | Implémentation du chiffre de Vernam
|
24-08-2014, 07h37
(Modification du message : 25-10-2014, 13h19 par EpicOut.)
Message : #1
|
|
EpicOut
Membre actif Messages : 121 Sujets : 10 Points: 23 Inscription : Feb 2012 |
[C] Cryptographie | Implémentation du chiffre de Vernam
Bonjour, Bonsoir
Aujourd'hui je vais vous présenter mon implémentation en C du chiffre de Vernam ou l'opération XOR qui découle de ce chiffrement, j'y ai vraiment mis du plaisir à le faire, pour une fois :-), c'est une implémentation relativement simple, relativement oui, j'en ai chier pour en venir à bout. Donc pour présenter le chiffrement de Vernam c'est un algorithme de chiffrement tout bête qui est "incassable", "inviolable", que ce soit par bruteforce ou autre techniques version grand-maître du cryptanalyste. On part du fait qu'il est impossible de trouver les additions qui ont formés une somme d'un entier: ? + ? = 100 | Où le premier point d'interrogation est le message original, et l'autre point d'interrogation, le masque jetable/clé, et 100 le message chiffré. Comment est-ce possible ? C'est effectivement impossible de retrouver le message original du fait que toute les possibilités sont possiblement possibles: 50+50 ; 51+49 ; 52+48 ; 53+47 ; etc... Plutôt bête non ? :-) Mais cependant on peut pas laisser un tel algorithme nous passer entre les doigts sans lui donner quelques (légers) désavantages. -Le masque/clé doit faire la même taille que le message original (oui, le chiffre de vernam est une opération bit à bit). -La clé doit être choisit aléatoirement. -Le masque/clé ne doit servir uniquement qu'une fois Et si on respecte scrupuleusement toutes ces conditions, on a le droit à une sécurité absolue, il parait. J'vous fait un exemple en live avec de l'ascii (non-étendu, de 0 à 127): On va prendre le chiffre à chiffrer M=1337 et la clé aléatoire (à 100%) C=FAAG , si on additionne ça (avec les correspondances décimales): 49|51|51|55 + 70|65|65|71 ___________ 119|116|116|126 , ce qui donne en ASCII: wtt~ Et s'il venait que votre addition dépasse la table ascii, auquel vous auriez une addition comme ceci: 49|51|51|105 + 70|65|65|71 ___________ 119|116|116|176 Ne vous inquiétez pas, nul besoin d'utiliser ascii étendu qui va jusqu'à 255, vous avez juste besoin de faire un modulo (ou une soustraction) du nombre maximum de caractères ascii ou de la norme sur laquelle vous travaillez, (si ça avait été du base64, un modulo 64 tout simplement) et en non étendu c'est 128, donc ça fait: 176%128 = 48 Maintenant place au code de mon implémentation, je doute qu'il soit digne d'un ingénieur informatique, donc n'hésitez pas à critiquer ou à me poser des questions si ça vous chagrine. Code C :
#include <stdio.h>
Plein de mouches peuvent rentrer en boucle close.
|
|
24-08-2014, 10h32
Message : #2
|
|
supersnail
Éleveur d'ornithorynques Messages : 1,614 Sujets : 72 Points: 466 Inscription : Jan 2012 |
RE: [C] Cryptographie | Implémentation du chiffre de Vernam
Well... pas mal tout ça (modulo quelques fautes d'orthographe et un "il parait" qui mériterait peut-être d'être plus détaillé).
Sinon quelques remarques concernant le code: Déjà utiliser rand() pour des petits jeux OK, mais pour faire de la crypto, ce n'est pas le meilleur générateur aléatoire qu'il soit (i.e si quelqu'un retrouve la graine utilisée dans srand, cette personne pourra déchiffrer tout le message, par exemple). Dans ce cas, il vaudrait mieux lire la sortie de /dev/urandom (qui lui est plus compliqué à prédire que son petit frère rand()) et travailler avec Ensuite (bon c'est de l'optimisation à 2 balles), plûtot que de faire une condition pour vérifier si la somme est < 255, autant directement faire le mod 256 (et peut-être utiliser des méthodes plus robustes que les manipulations de chaîne pour manipuler des données binaires, par exemple en transmettant la taille du masque avec le masque...) Puis un dernier pour la route: memset c'est bon, mangez-en !
Mon blog
Code : push esp ; dec eax ; inc ebp ; and [edi+0x41],al ; dec ebp ; inc ebp "VIM est merveilleux" © supersnail |
|
24-08-2014, 12h43
(Modification du message : 24-08-2014, 12h43 par b0fh.)
Message : #3
|
|
b0fh
Membre actif Messages : 210 Sujets : 17 Points: 309 Inscription : Jul 2012 |
RE: [C] Cryptographie | Implémentation du chiffre de Vernam
Hello,
Jolie introduction ! Pour compléter ce qu'écrit supersnail: le type char implémente déja naturellement l'arithmétique modulo 256. C'est tout à fait possible de travailler modulo 255, ce qui permet d'éliminer les NULs, mais il faut le faire de manière cohérente, par exemple pour l'addition de a et b, il faut: Code : (((a - 1) + (b - 1)) % 255) + 1 Il faut le faire dans un type suffisamment grand pour que ça ne wrappe pas avant le modulo (donc 16 bits au moins.) C'est aussi beaucoup, beaucoup plus lent que l'arithmétique mod 256. De cette manière on "projette" la plage effective 1-255 vers la plage 0-254, dans laquelle on utilise l'addition modulo 255. C'est faux de dire que le type signed char ne va "que" jusqu'a 127: en fait, l'arithmétique de base (addition, soustraction et multiplication) se comporte exactement de la même manière pour les types signed et unsigned, par quelque magie mathématique. La preuve: les instructions asm sont les mêmes. Ce qui change, par contre, ce sont les opérations de comparaison (jump greater/jump lesser vs jump above/jump below). Mais si on utilise le fait que le débordement produit naturellement une arithmétique modulo 256, il n'y a pas besoin de faire de comparaisons pour implémenter cet algo. Et sinon, amen pour la manipulation de données binaires avec une taille explicite. |
|
24-08-2014, 17h19
(Modification du message : 25-08-2014, 16h22 par EpicOut.)
Message : #4
|
|
EpicOut
Membre actif Messages : 121 Sujets : 10 Points: 23 Inscription : Feb 2012 |
RE: [C] Cryptographie | Implémentation du chiffre de Vernam
Alors tout d'abord, merci pour les retours les gars !
(24-08-2014, 10h32)supersnail a écrit : Déjà utiliser rand() pour des petits jeux OK, mais pour faire de la crypto, ce n'est pas le meilleur générateur aléatoire qu'il soit (i.e si quelqu'un retrouve la graine utilisée dans srand, cette personne pourra déchiffrer tout le message, par exemple). Dans ce cas, il vaudrait mieux lire la sortie de /dev/urandom (qui lui est plus compliqué à prédire que son petit frère rand()) et travailler avec Alors oui c'est vrai que /dev/urandom est plus "robuste", mais enfait mon programme se veut être "multiplateforme" étant donné que c'est que sur Linux, sur windows ou OSx on peut pas faire ça, je me demande si il y a une solution plus approprié ? Et merci aussi à toi b0fh pour les infos croustillantes, je ne savais pas du tout que le modulo se faisait tout seul ou qu'on pouvait écrire la clé aléatoire différemment
Plein de mouches peuvent rentrer en boucle close.
|
|
25-08-2014, 10h46
(Modification du message : 25-08-2014, 10h46 par supersnail.)
Message : #5
|
|
supersnail
Éleveur d'ornithorynques Messages : 1,614 Sujets : 72 Points: 466 Inscription : Jan 2012 |
RE: [C] Cryptographie | Implémentation du chiffre de Vernam
<troll>
Pourquoi faire de la crypto sur une passeoire ? Pour essayer de la transformer en casserole ? (ou en autobus) </troll> Sinon doit bien y avoir des fonctions de l'API Windows qui génère des nombres aléatoires "fiables" (ou pas en fait... c'est Windows :>) Edit: cf http://blogs.msdn.com/b/michael_howard/a...53379.aspx pour des nombres aléatoires "sûrs" pour la crypto
Mon blog
Code : push esp ; dec eax ; inc ebp ; and [edi+0x41],al ; dec ebp ; inc ebp "VIM est merveilleux" © supersnail |
|
« Sujet précédent | Sujet suivant »
|
Utilisateur(s) parcourant ce sujet : 5 visiteur(s)