Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les tutoriels > Non-Officiels > Programmation > C > [Tuto] Initiation au cryptage > Lecture du tutoriel

[Tuto] Initiation au cryptage

Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Avatar
Auteur : Greenflood
Note : 15 / 20 (12 votes)
Visualisations : 15 645

Plus d'informations Plus d'informations
Il peut être utile de crypter des données, par exemple si vous faites un jeu qui enregistre les meilleurs scores et que vous ne voulez pas que les joueurs s'amusent à bidouiller le fichier pour améliorer leurs meilleurs scores. Oui, on l'a tous fait ^^.

Aujourd'hui, je vous propose donc une initiation au cryptage. C'est vraiment sommaire, les bases des bases, mais ça a le mérite d'être accessible par n'importe qui ayant des connaissances classiques en maths (en gros vous devez connaître les opérations de base. Savoir utiliser les fonctions est fortement recommandé, mais pas obligatoire).
Sommaire du chapitre :
Icône du chapitre

La base

Continuons l'exemple cité précedemment. Vous avez un jeu qui stocke les 3 meilleurs scores dans un fichier, par exemple "high_score.bla". N'importe qui éditant ce fichier avec le bloc notes peut remplacer les scores par d'autres plus glorieux. Nous allons donc CRYPTER nos données (ouais ! :D ).
Comment que ça marche ?

Ce que nous allons faire, c'est appliquer une fonction au chiffre à stocker. Pour la théorie, nous allons donc dire que le score est représenté par la variable "score", le chiffre à stocker est la variable "stock", et la fonction y = 2X - 4.

On va donc insérer les lignes de code suivante dans le programme:

Code : C
1
stock = 2 * score - 4 ;


Puis on écrit la variable stock dans le fichier.
Si le score est de 20, on aura donc stock = 2 * 20 - 4 soit 36.

Mais quand notre programme veut afficher les scores réels, il faut décrypter les données en appliquant l'inverse de la fonction: dans le cas précédent, y = (X + 4) / 2.
Si la variable à décrypter est "crypted", on aura donc:

Code : C
1
score = (crypted + 4) / 2 ;


Toujours avec l'exemple précédent, nous avons:
score = (36 + 4) / 2 soit 20.

Et voilà !

Enfin, le truc c'est que l'on obtient des données cryptées prévisibles; je m'explique.
Pour un score de 20, on a 36.
Pour un score de 30, on a 56.
Pour un score de 40, on a 76.
Pour un score de 50, on a 96.

En s'y penchant un peu, on devine la fonction de cryptage facilement. Même sans aller jusque là, il suffit de mettre un chiffre très grand pour avoir un score très grand. On va donc améliorer tout ça ;).

Améliorations

A partir de là, deux choix s'offrent à nous. Soit éviter cette proportionnalitée du cryptage, soit faire en sorte que le programme "détecte" que l'on a bidouillé le fichier.

C'est à la deuxième option, plus abordable, à laquelle nous allons nous intéresser. Je ne pense pas que beaucoup d'entre vous veuillent rentrer dans les détails des fonctions non monotones et leurs inverses :-° .


Voilà donc comment nous allons faire.
Nous allons utiliser une fonction dont la plupart des images de son inverse soient décimales. Et notre score sera un entier. Vous avez saisi le principe ? Le programme décrypte la valeur, si elle est décimale, il détecte le bidouillage du fichier; sinon il utilise la valeur décryptée.

Cela implique donc que:
-les variables utilisées soient des double ou des float (rappelez vous, sinon l'ordinateur tronque et ça ne marchera pas ;) ).
-que votre chiffre sous sa forme initiale soit un entier; sinon, la valeur cryptée aura beau être authentique, le programme détectera un bidouillage qui n'a pas eu lieu.

Il nous manque juste une fonction...que vous devez connaître. Et oui, nous allons utiliser la fonction
y = X².

Pensez donc à inclure la librairie math.h.


Pour crypter le chiffre, nous le mettons au carré: dans le programme, mettre l'une des deux choses suivantes:
Code : C
1
crypted = chiffre * chiffre;


soit

Code : C
1
crypted = pow(chiffre, 2);


Et pour décrypter, nous utilisons la fonction "sqrt":

Code : C
1
decrypted = sqrt(chiffre);


Maintenant, il faut contrôler le chiffre décrypté.
Rappelez vous, il faut que ce soit un entier. Je détaille pour ceux qui ont du mal:

Notre score est un entier. Cela veut donc dire que la racine carré de son carré sera un entier.
Par exemple: 12 est un entier, et 12² = 144. Or racine carré de 144 vaut 12, qui est un entier.
Par contre, imaginons que notre bidouilleur remplace 144 par un nombre très grand, disons 10 000. Le programme calculera la racine carré de 100 000, soit environ 316.23. Notre programme verra que le chiffre est décimal, et affichera donc "fichier de scores corrompu" ou fera ce que vous voulez (par exemple effacer le fichier de scores en tant que punition ^^).

Maintenant il nous suffit juste d'écrire le code qui contrôlera le type du chiffre décrypté. Comment va t-on faire cela ? o_O

Souvenez vous, dans la partie 1 m@teo nous avait parlé des fonctions mathématiques. D'ailleurs, je cite:
Citation : m@teo21

Retenez quand même les fonctions floor, ceil, et pow, elles vous seront probablement utiles (même si vous ne programmez pas une calculatrice oui oui :p).


m@teo avait vu juste, nous allons utiliser la fonction floor. En effet, si le chiffre est un entier, floor(chiffre) sera égal au chiffre. Employons donc la portion de code suivant:

Code : C
1
2
3
4
if (floor(chiffre) == chiffre)
    printf("OK !");
else
    printf("Pas OK !");


Je ne vais pas commenter ce code, à votre niveau il ne me semble pas que ce soit la peine.

Voilà, c'est fini sur la théorie. La dernière partie va parler (très brièvement) des limites de cette méthode.

Limites de la méthode

La méthode que nous venons de voir à l'avantage d'être simple d'accés, mais le défaut d'être assez limitée.
Notez que cependant, pour des Zér0s comme nous, ce n'est pas vraiment la peine de chiffrer nos données avec les même méthodes que la CIA ^^ .


Premier défaut: ça ne marchera pas avec des nombres négatifs pour une raison toute bête:

Si vous mettez votre nombre négatif au carré, puis que vous calculez sa racine carré, vous aurez la valeur absolue du chiffre. Exemple: -13² vaut 169, et racine carré de 169 vaut 13. Votre chiffre décrypté ne sera donc pas le même que le chiffre initial.
Enfin, d'une manière générale on ne se sert pas trop des négatifs, surtout dans les scores d'un jeu.
Si vous tenez absolument à crypter des chiffres négatifs, vous pouvez utiliser une fonction impaire, tel X au cube (qui sera décryptée par la fonction racine cubique de X).
Si vous voulez améliorer vos techhniques de cryptage, je ne peux vous donner qu'un conseil: écoutez en cours de mathématiques :p vous verrez que maths et prog' vont bien ensemble, et que la connaissance du premier aide pour l'apprentissage du second.


Second défaut: On peut facilement deviner la méthode de cryptage soit en extrapolant sur la fonction de cryptage, soit à l'aide d'un désassembleur.

Gné ?


Bon mon but n'est ni de vous donner des cours de maths ni de vous expliquer comment fonctionne un désassembleur (parce qu'au passage il faudrait que je vous explique l'assembleur, ce qui prend plusieurs années à maîtriser, et que moi même je ne maîtrise pas :-° ). Cependant, je vais vous détailler rapidement ces deux méthodes.

1) Extrapolation d'une fonction


En gros, on récupère pleins de valeurs cryptées et leur équivalent non crypté. On représente les points sur un système de coordonnées cartésien, et on essaye de voir si cela s'apparente à une fonction que l'on connaît. Avec un peu d'expérience mathématique (et suivant la simplicité de la fonction ;) ), on retrouve facilement. Et le tour est joué.


2) Le désassembleur


Pour les fonctions plus complexes, sur lesquelles on ne peut pas extrapoler, on utilise un désassembleur.

Re-gné ?


Bon, un désassembleur sert à désassembler un programme, c'est à dire récupérer le code d'un programme en assembleur.

Vous savez que vos exécutables sont que des 0 et des 1 ? Et bien en fait l'assembleur est un langage qui met en forme ces 0 et 1. La syntaxe demeure cependant la même, cependant au lieu d'avoir quelque chose comme:
Code : Autre
1
0101 0110 0001 1100

on a quelque chose comme:
Code : Autre
1
2
3
ld e,a

add hl, de


Ce langage est extrêmement compliqué à comprendre, puisque c'est un moyen quasi direct de communiquer avec le processeur. Notez que je dis ce langage; ce serait plutôt ce type de langage car chaque type de processeur à son type d'assembleur (x86 par exemple pour les processeurs Intel actuels).


Bref, un désassembleur nous donne le code en assembleur d'un fichier exécutable. Pour quelqu'un qui maîtrise parfaitement l'assembleur, c'est comme voir le code source de votre programme. Rassurez vous, maîtriser l'assembleur, je le repète, prend plusieurs années (dans le meilleur des cas)^^.
Sans en arriver à de tels extrêmes, il est possible (mais bien au delà du niveau d'un zér0 moyen), de voir ce qui se passe dans le processeur lors de l'éxécution d'un programme.

Voilà, c'était une initiation vraiment basique, à un niveau plus élevé on ne se sert pas de ça, mais pour des Zér0s qui font des programmes amateurs qui ne dépasseront pas (pour l'instant) un cercle restreint d'internautes, ça reste convenable.

Tiens, et si je faisais un tuto pour le niveau supérieur ? :p


License


Image utilisateur
Retour en haut Retour en haut


Créé : le 29/04/2006 à 19:08:32
Modifié : le 22/08/2008 à 16:09:43
Avancement : 100%
Licence : Copie non autorisée

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | Fil RSS | XHTML 1.0 | CSS 2.0
Édité par Simple IT SARL : Nous contacter | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 84 Zéros connectés | Requêtes SQL 9 requêtes | Temps de génération de la page : Total (SQL) 0.0673s (0.0578s)