Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les tutoriels > Non-Officiels > Programmation > C > [TP] Réaliser un crypteur de fichiers à l'aide de la fonction XOR > Lecture du tutoriel

[TP] Réaliser un crypteur de fichiers à l'aide de la fonction XOR

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 : Geo.669
Note : 18 / 20 (19 votes)
Visualisations : 12 226

Plus d'informations Plus d'informations
Bienvenue, chers Zér0s. Vous allez lire mon tout premier tutorial sur ce site !!
Euh... T'es pas encore prêt pour faire de bons tutoriaux alors... J'me tire !!


Ah non, restez donc :p Je n'ai pas encore tout dit. Voici de quoi va parler ce tutorial :
- La fonction XOR dans son ensemble.
- Coder un programme qui crypte nos fichiers sous la fonction XOR en C.
- Tester et s'amuser. :)
Je vous préviens sur les prérequis avant de terminer mon introduction : il vous faudra avoir lu les cours de M@teo21 sur le C/C++.


Bon, rien d'autre à dire. On y va ? :)
Sommaire du tutoriel :
Icône du chapitre

La fonction XOR dans son ensemble

Bien, avant de faire notre programme, nous allons parler de la fonction XOR.
Euh ouais... C'est quoi ce machin ? Xylophone Ou Rayonnement ? o_O

Non non, pas du tout :lol:
Le XOR, c'est le fameux "OU exclusif", très répandu dans les algorithmes de cryptages modernes. Il consiste tout simplement à comparer les bits un à un et de renvoyer 1 SI ET SEULEMENT SI LES DEUX OPERANDES SONT DIFFERENTES.

Voici la table de vérité :
O + 0 = 0
1 + 0 = 1
0 + 1 = 1
1 + 1 = 0

Cela vérifie bien notre hypothèse. On voit bien que le bit 1 est renvoyé lorsque les deux bits à comparer sont différents. Voyons comment se passe le XOR de deux octets.

Déjà, il faut savoir qu'un octet est codé sur 8 bits.
Si vous ne savez pas ce qu'est un octet, je vais de suite vous l'expliquer.

L'octet est tout simplement l'unité de mémoire de l'ordinateur. Il est codé sur 8 bits. Un bit peut prendre deux formes différentes : 0 ou 1 (c'est pour cela que le langage BInaire est intitulé "Base 2"). Il y a aussi le quartet, codé sur 4 bits.
Un chiffre hexadécimal étant codé sur 4 bits, il en faut 2 pour faire un octet, vous me suivez ? :p

Si vous n'avez pas les notions de nombre décimal, hexadécimal, binaire... et j'en passe, je vous envoie un très bon article du Wikipédia : http://fr.wikipedia.org/wiki/ASCII.


Bien, prenons par exemple la lettre g et la lettre l.
La lettre g a son code hexadécimal, tout comme la lettre l.
Comme nous l'indique le tableau de conversion de l'article de Wikipedia donné plus haut, g correspond au chiffre hexadécimal (en base 16) 67, et l correspond au chiffre hexadécimal 6C.


Bon, maintenant que nous avons nos valeurs hexadécimales, nous allons les traduire en binaire ! :D
67 donne 1100111 et 6C donne 1101100 (regardez la colonne "base 2" du tableau).

Xorons ! :magicien:
1 + 1 = 0
1 + 1 = 0
0 + 0 = 0
0 + 1 = 1
1 + 1 = 0
1 + 0 = 1
1 + 0 = 1

Voilà, on obtient le nombre binaire 0001011, il correspond au chiffre hexadécimal 0B. Notez que celui-ci est proche de 00. Plus les chiffres hexadécimaux sont proches, plus leur XOR sera faible.

Ok, mais je fais quoi avec 0001011 ou 0B ?!

J'attendais cette question !
Si vous faites un XOR avec 0B et 67, vous obtiendrez... 6C, donc la lettre l ! Vous comprenez pourquoi la fonction XOR est utilisée dans les algorithmes de cryptage ?

C'est une fonction réversible, cela signifie que l'on peut non seulement crypter avec une clef, mais réencrypter par dessus avec cette même clef ne fera que décrypter notre texte.

Compris pour la fonction XOR ? Ok, passons à la partie C ! :D

Coder un programme qui crypte nos fichiers sous la fonction XOR en C

Bien, maintenant que vous avez à peu près idée de ce qu'est la fonction XOR, nous allons faire un programme qui crypte lui-même un fichier à l'aide de cette fonction. Voici un aperçu du cahier des charges :
Et euh... Comment je fais pour le XOR moi ? Je ne pense pas avoir appris ça...

Très simple. Si vous avez des notions en PHP, vous le savez déjà, pour certains d'entre vous.
Voici la syntaxe pour comparer deux octets avec un XOR :
Code : C
1
int xoring = 0x60 ^ 0x9B;

Ici, deux valeurs hexadécimales sont comparées, et la variable xoring renverra en résultat le xor du chiffre hexadécimal 60 avec le chiffre hexadécimal 9B, c'est-à-dire : FB :)

Mais attends, je viens de penser à un truc ! Si on a une clef de cryptage, et qu'elle fait par exemple 6 caractères et que le fichier fait un mégaoctet, donc 1 million de caractères, les 6 premiers seront seulement cryptés ? :euh:

Mais nooon. Il faut tout simplement se déplacer dans la chaîne de caractères qui constitue la clef et revenir au début de la clef si vous êtes à la fin.

J'estime avoir tout dit. Je vous laisse coder. :)

...

...

STOOOooooOoOOooOOoP ! Professeur VeNoM630 relève les copies !
Je vous félicite si vous avez réussi à faire un programme capable de crypter un fichier et de le décrypter pour revenir au point de départ.
Je m'explique : j'ai un fichier prog.exe, je le crypte en prog2.exe avec la clef 'bahamut' et je recrypte prog2.exe en prog3.exe avec la même clef 'bahamut'. Si prog3.exe est une parfaite copie de prog.exe, vous pouvez être fier de vous.

Voici mon code :
Code : C
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
    xor.c
    permet de crypter tout type de fichier à l'aide de la fonction XOR
    by VeNoM630
*/

#include <stdio.h>
#include <stdlib.h>

/* On déclare notre prototype de fonction qui va :
    ouvrir un fichier en lecture,
    lire les octets, les 'xorer'
    et écrire dans le fichier ouvert en écriture.

    ici, "fin" correspond au pointeur de fichier lu,
    "fout" correspond au pointeur de fichier d'écriture,
    et "key" correspond à la clef de cryptage.
*/
void ReadXorAndWrite(FILE *fin,FILE *fout,char key[30]);

/*
    On va ensuite déclarer nos pointeurs de fichiers
    et nos variables dans la fonction main
*/
FILE *fptr1;
FILE *fptr2;

char filename1[30];
char filename2[30];
char clef[30];

/* On lance la fonction principale du programme : main() */
int main()
{
    /* On demande quel fichier il faut crypter */
    printf("Nom du fichier a analyser:\t");
    scanf("%s",filename1);

   /* On fait de même pour le fichier crypté à créer */
    printf("Nom du fichier crypte a creer :\t");
    scanf("%s",filename2);

    /* On demande la clef de cryptage XOR */
    printf("Entrez votre clef de cryptage :\t");
    scanf("%s",clef);

    /* Voila, l'utilisateur a soumis toutes les données,
    on va maintenant vérifier si on arrive à lire notre
    fichier 'filename1' en lecture binaire */
    if((fptr1 = fopen(filename1,"rb")) == NULL)
    {
        /* Si l'ouverture a echoué, on renvoie un message d'erreur */
        printf("Erreur, impossible d'ouvrir %s en lecture.\n",filename1);
        system("pause > nul");
        exit(EXIT_FAILURE);
    }
    else
    {
        /* Sinon, on vérifie si on arrive à écrire dans
        notre fichier 'filename' en mode ecriture binaire.
        Si le fichier n'existe pas, il est créé automatiquement */
        if((fptr2 = fopen(filename2,"wb")) == NULL)
        {
            /* Si l'ouverture a echoué, on renvoie un message d'erreur */
            printf("Erreur, impossible d'ouvrir %s en ecriture.\n",filename2);
            system("pause > nul");
            exit(EXIT_FAILURE);
        }
        else
        {
            /* Sinon, tout est bon, on exécute notre fonction que
            nous allons décrire ci-dessous (le prototype est déclaré
            avant la fonction main() */
            ReadXorAndWrite(fptr1,fptr2,clef);

            /* Puis on ferme les fichiers */
            fclose(fptr1);
            fclose(fptr2);
        }
    }
    /* On renvoie '0' pour montrer que le programme se termine normalement. */
    return 0;
}

/* Maintenant, on va décrire la fonction ReadXorAndWrite() */
void ReadXorAndWrite(FILE *fin,FILE *fout,char key[30])
{
    /* On va déclarer trois variables :
    - La première est celle qui va recevoir en mémoire
    l'octet lu dans fin;
    - La seconde est la variable qui contiendra en mémoire
    le XOR de l'octet lu et l'octet de la clef;
    - La troisième est une variable qui s'incrémentera
    au fil du temps pour se déplacer dans key[] et qui
    reviendra au début de la chaîne. */
    char ch;
    int xoring;
    int i = 0;

    /* On va ensuite faire une boucle infinie qui s'arrêtera en cas
    d'échec de lecture de fin, donc si il n'y a plus rien à lire dans
    fin */
    while(1)
    {
        /* Si l'on arrive plus à lire dans fin pour
        mémoriser en adresse mémoire de ch un élément qui correspond
        à l'octet, on 'break' pour sortir de la boucle */
        if(!fread(&ch,sizeof(char),1,fin))
            break;
        else
        {
            /* Sinon, on vérifie que nous ne sommes pas à la fin de la chaîne
            de key, donc si l'octet actuel de key n'est pas '\0'. */
            if(key[i] == '\0')
            {
                /* On remet le compteur i à 0 pour revenir en début de chaîne */
                i = 0;
            }
            /* On affecte à 'xoring' le xor de l'octet de fin et celui de la clef
            grâce à l'opérateur logique '^' */
            xoring = ch ^ key[i];

            /* Et enfin on écrit dans fout la valeur de xoring ! */
            fwrite(&xoring,sizeof(char),1,fout);
        }
        /* On a fini la condition, on incrémente 'i' et on ferme la boucle */
        i++;
    }
    /* On fait savoir à l'utilisateur que l'opération est terminée */
    printf("Le XOR est termine !\n");
    system("pause > nul");

    /* On referme la fonction, et c'est la fin du code */
}


Et oui, c'est fini. Je l'ai commenté exprès pour vous.

Voici ce que je peux obtenir sous exécution :
Code : Console
Nom du fichier à analyser: image.bmp

Nom du fichier crypte a creer : image_crypted.txt

Entrez votre clef de cryptage :

VeNoM630

Le XOR est termine !

_


Puis :
Code : Console
Nom du fichier à analyser: image_crypted.txt

Nom du fichier crypte a creer : image2.bmp

Entrez votre clef de cryptage :

VeNoM630

Le XOR est termine !

_


Et vous constaterez que "image.bmp" et image2.bmp" sont parfaitement identiques !!

C'est tout :)

Le tutoriel est déjà terminé, bouuuh... Enfin, j'espère de tout cœur que vous avez appris des choses sympathiques, et que vous n'aurez plus aucun souci de confidentialité avec qui que ce soit ^^

Pour toute question ou remarque, n'hésitez pas à m'envoyer un message privé. Je me ferais une joie de vous répondre :D
Retour en haut Retour en haut


Créé : le 06/10/2006 à 20:15:15
Modifié : le 22/08/2008 à 16:06:51
Avancement : 100%
Licence : Copie non autorisée

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | RSS tutoriels | RSS news
Édité par Simple IT SARL : Nous contacter | Notre blog | 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 196 Zéros connectés | Requêtes SQL 8 requêtes | Temps de génération de la page : Total (SQL) 0.1181s (0.1063s)