IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Chiffrage de fichier avec XOR


Sujet :

C++

  1. #1
    Membre confirm�
    Profil pro
    Inscrit en
    Ao�t 2004
    Messages
    152
    D�tails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 152
    Par d�faut Chiffrage de fichier avec XOR (et cl� md5)
    Bonjour � tous,

    J'essaie de chiffrer un fichier � l'aide d'une cl� et de l'op�ration xor sur tout le fichier. Bien entendu la cl� est plus petite que le fichier � chiffrer du coup la cl� est parcourue en boucle.

    Cependant j'ai un petit probl�me au niveau du d�chiffrage, le programme se lance mais quitte directement sans rien faire. On dirait qu'il plante et il y a une erreur m�moire (instruction xxx ... impossible de read)

    J'ai peut-�tre commis une erreur dans le chiffrage puisque je suis totalement novice en chiffrage et en C++ en plus. D'apr�s ce que j'ai compris je peux utiliser la m�me op�ration que le chiffrage, au niveau du xor, pour d�chiffrer, est-ce exacte ?

    Sinon voici mon code :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    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
    #include <cstdlib>
    #include <iostream>
    #include <fstream>
     
    using namespace std;
     
    void crypt(const char *text, const char *key, char *crypted) {
         unsigned int j = 0;
         for (unsigned int i = 0; i<strlen(text); i++) {
             if (j >= strlen(key)) {
                   j=0;
             }
             crypted[i] = text[i]^key[j];
             j++;
         }
    }
     
    int main(int argc, char *argv[])
    {
        char *key = "9cdfb439c7876e703e307864c9167a15";
        fstream file_in("text.txt", ios::in|ios::binary);
        fstream file_out("text-out.txt", ios::out|ios::binary);
        int iter = 0;
        const int tranche = 192;
        char buffer[tranche];
        while (!file_in.eof()) {
              file_in.getline(buffer, (iter*tranche)+tranche);
              char tmp[tranche];
              crypt(buffer, key, tmp);
              strcpy(buffer, tmp);
              file_out.write(buffer, strlen(buffer));
              iter++;
        }
        file_in.close();
        file_out.close();
     
        cout << "\nFini\n";
        system("PAUSE");
        return 0;
    }
    Ce serait pour apr�s mais peut-�tre aussi pouvez-vous m'aider pour que la cl� key soit interpret�e comme du hex car pour le moment c'est du char.
    J'ai s�rement fait des erreurs b�tes et coder comme un pied mais j'esp�re que vous saurez me mettre sur le bon chemin !

    Merci d'avance.

  2. #2
    Membre �prouv� Avatar de amaury pouly
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    157
    D�tails du profil
    Informations personnelles :
    �ge : 36
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 157
    Par d�faut
    Cette ligne pose probl�me:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
     
    file_in.getline(buffer, (iter*tranche)+tranche);
    Puisque "getline" attends comme second param�tre la taille du buffer, or ton buffer est de taille "tranche" et non pas de taille (iter*tranche)+tranche.

  3. #3
    Membre confirm�
    Profil pro
    Inscrit en
    Ao�t 2004
    Messages
    152
    D�tails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 152
    Par d�faut
    Ah oui �a change tout, par contre j'ai toujours un gros probl�me avec les fichiers. Je n'obtient pas les m�mes fichiers � l'arriv�e.

    Voici le bout de code simplifi� :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    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
    int main(int argc, char *argv[])
    {
        char *key = "9cdfb439c7876e703e307864c9167a15";
        char *filename_in = "image-tocrypt.jpg";
        char *filename_out = "image-out.jpg";
        fstream file_in(filename_in, ios::in|ios::binary);
        fstream file_out(filename_out, ios::out|ios::binary);
     
        if (!file_in || !file_out) {
              cout << "Impossible d'ouvrir !";
              return 0;
        }
     
        int iter = 0;
        const int tranche = 192;
        char buffer[tranche];
     
        // Determine la longueur du fichier
        file_in.seekg(0, ios::end);
        int file_inlength = file_in.tellg();
        file_in.seekg(0, ios::beg);
     
        while (iter*tranche < file_inlength) {
              file_in.read(buffer, tranche);
              //char tmp[tranche];
              //crypt(buffer, key, tmp);
              //strcpy(buffer, tmp);
              file_out.write(buffer, tranche);
              iter++;
        }
        file_in.close();
        file_out.close();
     
        cout << "\nFini\n";
        system("PAUSE");
        return 0;
    }
    J'ai test� avec une photo et si j'utilise getline c'est illisible alors qu'avec read c'est presque parfait. J'arrive � voir la photo mais il y a quelques octets en trop, 124 pour �tre pr�cis. Poids avant: 33'860 o ; apr�s : 33'984 o. S�rement une erreur dans la boucle mais laquelle ?

  4. #4
    Membre �prouv� Avatar de amaury pouly
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    157
    D�tails du profil
    Informations personnelles :
    �ge : 36
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 157
    Par d�faut
    Le probl�me c'est que getline s'utilise principalement avec des fichiers texte, or avec des fichiers binaire, cela n'a pas de sens. Je te conseille d'utiliser read au lieu de getline. Notamment, getline va ignorer tous les '\n' qui peuvent tout � fait appara�tre al�atoirement dans un fichier binaire.

  5. #5
    Membre confirm�
    Profil pro
    Inscrit en
    Ao�t 2004
    Messages
    152
    D�tails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 152
    Par d�faut
    En effet je viens de l'apprendre � mes d�pends. Je viens de corriger la copie est conforme (les deux MD5 concordent).

    Maintenant il y a un probl�me avec le chiffrage. En effet j'ai remarqu� que tout � l'air juste, j'ai v�rifi� par-ci par l� c'est juste sauf le dernier byte o� le xor semble �tre faux.

    J'ai essay� de faire le d�chiffrage mais c'est totalement faux, je retrouve � peine 50% des donn�es. J'ai regard� en HEX et je voyais � peu pr�s la moiti� qui revenait par rapport au fichier original.

    Je suis persuad� que vous pouvez m'aider, voici mon code actuellement :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    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
    #include <cstdlib>
    #include <iostream>
    #include <fstream>
     
    using namespace std;
     
    void crypt(const char *text, const int length, const char *key, char *crypted) {
         int j = 0;
         for (int i = 0; i<length; i++) {
             if (j >= (signed) strlen(key)) {
                   j=0;
             }
             crypted[i] = text[i]^key[j];
             j++;
         }
    }
     
    int main(int argc, char *argv[])
    {
        char *key = "9cdfb439c7876e703e307864c9167a15";
        char *filename_in = "image-tocrypt.jpg";
        char *filename_out = "image-out.jpg";
        fstream file_in(filename_in, ios::in|ios::binary);
        fstream file_out(filename_out, ios::out|ios::binary);
     
        if (!file_in || !file_out) {
              cout << "Impossible d'ouvrir !";
              return 0;
        }
     
        int iter = 0;
        const int tranche = 192;
        char buffer[tranche];
     
        // Determine la longueur du fichier
        file_in.seekg(0, ios::end);
        int file_inlength = file_in.tellg();
        file_in.seekg(0, ios::beg);
     
        while (iter*tranche < file_inlength) {
              int readByte;
              readByte = tranche;
              if (iter*tranche+tranche > file_inlength)
                 readByte = file_inlength-iter*tranche;
              strcpy(buffer, "");
              file_in.read(buffer, readByte);
              char tmp[tranche];
              crypt(buffer, readByte, key, tmp);
              strcpy(buffer, tmp);
              file_out.write(buffer, readByte);
              iter++;
        }
        file_in.close();
        file_out.close();
     
        cout << "\nFini\n";
        system("PAUSE");
        return 0;
    }
    Merci d'avance !

    PS: Apparement le chiffrage est faux, une partie des donn�es est chiffr�e mais pas tout. J'ai fais pass� un fichier texte et on voit clairement des donn�es, y'a quelque chose qui cloche ! (Normal du coup que le d�chiffrage ne fonctionne pas).

  6. #6
    Membre �m�rite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par d�faut
    J'esp�re que ce que tu as � chiffrer n'est pas important. Le cryptage avec un XOR utilis� plus d'une fois, c'est � peu pr�s �quivalent � donner le fichier en clair (alors que, paradoxalement, utilis� une seule fois, il est prouv� que c'est absolument ind�chiffrable ...).

  7. #7
    Membre confirm�
    Profil pro
    Inscrit en
    Ao�t 2004
    Messages
    152
    D�tails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 152
    Par d�faut
    Citation Envoy� par 10_GOTO_10 Voir le message
    J'esp�re que ce que tu as � chiffrer n'est pas important. Le cryptage avec un XOR utilis� plus d'une fois, c'est � peu pr�s �quivalent � donner le fichier en clair (alors que, paradoxalement, utilis� une seule fois, il est prouv� que c'est absolument ind�chiffrable ...).
    Pour le moment je fais des tests sur des fichiers totalement inutile. Par contre tu as mal compris ce que je voulais dire. Mon code actuellement ne chiffre pas correctement, on dirait qu'il chiffre partiellement et je parle bien de chiffrer la premi�re fois donc 1 seul fois l'op�ration crypt() ! J'ai constat� ceci car le fichier, une fois pass� dans crypt() a des parties (mots voire phrases) totalement non-chiffr�es, donc lisibles !

  8. #8
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    D�tails du profil
    Informations personnelles :
    �ge : 35
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par d�faut
    Citation Envoy� par 10_GOTO_10 Voir le message
    J'esp�re que ce que tu as � chiffrer n'est pas important. Le cryptage avec un XOR utilis� plus d'une fois, c'est � peu pr�s �quivalent � donner le fichier en clair (alors que, paradoxalement, utilis� une seule fois, il est prouv� que c'est absolument ind�chiffrable ...).
    Il est ind�chiffrable seulement si la longueur de cl� (tirer au hasard) est aussi longue que la phrase � crypter.

  9. #9
    Membre �prouv� Avatar de amaury pouly
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    157
    D�tails du profil
    Informations personnelles :
    �ge : 36
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 157
    Par d�faut
    Je ne sais pas si c'est li� mais le fait est que ta cl� est extr�mmement pauvre: elle n'utilise que les caract�re 0-9 et a-f c'est � dire seulement 16 sur 256 possibles et qui ont la facheuse tendance d'avoir beaucoup de bits en commun. Si tu veux une cl�e en hexad�cimal il ne faut pas t'y prendre comme cela. Sinon je ne vois pas d'autre erreurs mais cela ne veut pas dire qu'il n'y en a pas.

  10. #10
    Membre confirm�
    Profil pro
    Inscrit en
    Ao�t 2004
    Messages
    152
    D�tails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 152
    Par d�faut
    Voil� j'ai bien avanc� ! J'ai enfin r�ussi � trouver pourquoi mon code ne semblait pas chiffrer tout mon fichier. Ta th�rorie amaury pouly n'est pas juste, le coupable se trouvait dans l'instruction suivante :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    strcpy(buffer, tmp);
    file_out.write(buffer, readByte);
    Pourquoi ? Je ne sais pas mais on dirait que certains octets restait dans le buffer � la lecture et que strcpy n'�crasait pas l'ancien buffer par les octets chiffr�s, du coup il devait rester des parties du fichier venant directement de la lecture et donc en clair !

    Pour r�pondre � Goten, je compte utiliser une cl� assez courte car une cl� de la longueur du fichier est peu pratique et que je n'ai pas besoin d'un chiffrage si avanc�. Malgr� qu'il soit "pauvre", �a me suffira je pense. Donc je voulais dire que je parcoure la cl� autant de fois qu'il le faut pour chiffrer l'int�gralit� du fichier (�a revient � dire que la cl� est de la taille du fichier mais totalement redondant, donc faillible c'est vrai). Pour am�liorer cela je pourrais prendre une cl� SHA512 ou plus par exemple.

    Voici mon code actuelle :


    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    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
    #include <cstdlib>
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include <math.h>
     
    using namespace std;
     
    // Chiffrage
    // -- selon une clé char
    void crypt(char *text, int length, char *key, char *crypted) {
         int j = 0;
         for (int i = 0; i < length; i++) {
             if (j%strlen(key) == 0) {
                   j=0;
             }
             crypted[i] = text[i] ^ key[j];
             j++;
         }
    }
     
    // -- selon une clé en binary
    void crypt(char *text, int length, double key, char *crypted) {
         int j = 0;
         char keychar[25];
         sprintf(keychar, "%15.0f", key);
         cout << "! " << keychar << endl;
         for (int i = 0; i < length; i++) {
             if (i%strlen(keychar) == 0) {
                   j=0;
             }
             crypted[i] = text[i] ^ keychar[j];
             j++;
         }
    }
     
    double convert_key_binary(char *key) {
         double result;
         result = 0;
         for (unsigned int i = 0; i < strlen(key); i++) {
             int tmp;
             char car = key[ ((strlen(key)-1)-i) ];
             switch ( car ) {
                    case '0': tmp = 0; break;
                    case '1': tmp = 1; break;
                    case '2': tmp = 2; break;
                    case '3': tmp = 3; break;
                    case '4': tmp = 4; break;
                    case '5': tmp = 5; break;
                    case '6': tmp = 6; break;
                    case '7': tmp = 7; break;
                    case '8': tmp = 8; break;
                    case '9': tmp = 9; break;
                    case 'a': tmp = 10; break;
                    case 'b': tmp = 11; break;
                    case 'c': tmp = 12; break;
                    case 'd': tmp = 13; break;
                    case 'e': tmp = 14; break;
                    case 'f': tmp = 15; break;
                    default : cout << "Error"; return 0;
             }
             result += tmp*( pow(16, ((strlen(key)-1)-i)) );
         }
         return result;
    }
     
    int main(int argc, char *argv[])
    {
        char *key = "9cdfb439c7876e703e307864c9167a15";
        double keyhex = convert_key_binary(key);
        printf("%f\n", keyhex);
        char *filename_in = "text.txt";
        char *filename_out = "text-out.txt";
        fstream file_in(filename_in, ios::in|ios::binary);
        fstream file_out(filename_out, ios::out|ios::binary);
     
        if (!file_in || !file_out) {
              cout << "Impossible d'ouvrir !";
              return 0;
        }
     
        int iter = 0;
        const int tranche = 192;
        char buffer[tranche];
     
        // Determine la longueur du fichier
        file_in.seekg(0, ios::end);
        int file_inlength = file_in.tellg();
        file_in.seekg(0, ios::beg);
     
        while (iter*tranche < file_inlength) {
              int readByte;
              readByte = tranche;
              if (iter*tranche+tranche > file_inlength)
                 readByte = file_inlength-iter*tranche;
              strcpy(buffer, "");
              file_in.read(buffer, readByte);
              char tmp[readByte];
              crypt(buffer, readByte, key, tmp);
              /*strcpy(buffer, tmp); <-- Si je décommente, 
                               certaines parties du fichier 
                               reste visibles après le chiffrage !!! */
              file_out.write(tmp, readByte);
              iter++;
        }
        file_in.close();
        file_out.close();
     
        cout << "\nFini\n";
        system("PAUSE");
        return 0;
    }
    Comme vous pouvez le voir il s'est agrandit, j'ai rajout� une fonction surcharg�e pour prendre en charge la cl� en binaire � proprement dit. Je veux dire par l� que ma cl� key est en fait un checksum d'un mot de passe. C'est � dire que normalement ce checksum est en binaire � l'origine et que pour des raisons de facilit�s il est plus facile de l'exprimer en hex, c'est plus facile � transf�rer.

    J'ai donc un mot de passe xxx qui passe dans un MD5 et donne en hex "9cdfb439c7876e703e307864c9167a15". Ici C++ le reconnait comme une chaine et c'est dans le but de le convertir dans son format d'origine (en bytes) que j'ai cr�er la deuxi�me fonction crypt.
    Je commence par convertir key en decimal (base 16 > 10) �a fait un �norme nombre de l'ordre de 10e+38 (16^31), j'utilise ma fonction convert_key_binary pour se faire. Ensuite j'envoie ce `double` � la fonction crypt qui convertit celui-ci en char pour pouvoir le parcourir octet par octet.

    D'apr�s moi ma conversion est totalement fausse car j'obtient un chiffre avec pleins de z�ros (108536561009105580000000000000000000000). L'ordre de grandeur est gard� mais o� sont tout mes chiffres !? (Pour info, c'est l'instructions printf au d�but de mon main qui affiche ce nombre.)

    Est-ce que ma m�thode pour convertir l'hex en d�cimal est juste ?
    Est-ce qu'il y aurait une autre m�thode pour appliquer xor � ma cl� mais en la convertissant en binaire avant ?

    Un petit coup de pouce pour la convertion ne serait pas de refus. Merci d'avance.

  11. #11
    Membre chevronn�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Sant�

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par d�faut
    M�me si un double peut contenir ton �norme nombre, il ne peut pas garder tous les chiffres (un double c'est comme un float, mais avec deux fois plus de chiffres "significatifs", si on peut dire).
    Si tu veux quelque chose de pr�cis, il faut absolument travailler sur des entiers (et je pense que tu devra te servir d'une biblioth�que sp�cialis�e, car je ne pense pas qu'un nombre de l'ordre de 10^31 puisse �tre g�r� par les types standards).

  12. #12
    Membre �prouv� Avatar de amaury pouly
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    157
    D�tails du profil
    Informations personnelles :
    �ge : 36
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 157
    Par d�faut
    Je viens de comprendre pourquoi, le strcpy m'avait �chapp� ! En effet, strcpy copie une cha�ne de caract�re dans une autre, or tu ne manipules pas de cha�nes de caract�res !
    Autrement dit, ton strcpy peut potentiellement faire n'importe quoi, c'est � dire �crire moins que readBytes(c'est ton cas visiblement) ou plus(et faire un buffer overflow et tout ce qui suit...).

    Concernant le double c'est assez horrible d'utiliser un tel code �tant donn� que si tu ne fais pas attention, le r�sultat peut �tre non d�terministe(!). De plus, ton immense code(9cdfb439c7876e703e307864c9167a15) ne peut pas tenir dans un double:
    9cdfb439c7876e703e307864c9167a15 -> 2,08521104953385306819e38
    Or log(2,08521104953385306819e38)/log(2) -> 127
    Donc pour stocker ton nombre il faut 128 bit, or un double n'en fait que 64...
    Je te conseille donc soit de r�duire ta clef et de la stocker dans un entier(long), soit de la garder dans une cha�ne de caract�re.

  13. #13
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Aussi, n'oubliez pas qu'un \0 stoppe une cha�ne, donc un cryptage XOR pur n'est pas adapt� aux cha�nes de caract�res (le r�sultat peut �tre une cha�ne tronqu�e).

    Pour corriger cela, deux options: Soit traiter les donn�es comme un tableau d'octets (donc, plus de strlen() ou strcpy() nulle part), soit mettre une petite exception dans le xor:
    Code C++ : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    if(text[i] == key[i])
    	crypted[i] = text[i];
    else
    	crypted[i] = text[i] ^ key[i];
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre �clair�
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Par d�faut
    je pencherais largement pour la premi�re option... elle permet de se dispenser de savoir ce qu'on traite comme information.

  15. #15
    Membre confirm�
    Profil pro
    Inscrit en
    Ao�t 2004
    Messages
    152
    D�tails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 152
    Par d�faut
    Merci pour vos r�ponses,

    Je viens de passer par le mode binaire de md5sum et le code binaire de la cl� n'est pas long du tout (16 bytes). Donc 128 bits => 16 bytes en effet. Mais �a semble tout petit comme �a !!!

    Apparemment il est grand, bon je vais pouvoir utiliser gmp puisque je l'ai install� et test� � l'occasion. J'esp�re que �a prendre pas trop de m�moire vive. Sinon �a para�t totalement ..... ab�rrant qu'il n'y ait pas de fonction pour les puissances avec mpz_class !!! J'ai bien regard� 3x la doc sans vraiment comprendre, il n'expliquent pas vraiment. Si finalement je n'utilise pas gmp au vu de ce que vous allez me conseillez c'est pas grave �a pourrait toujours servir.

    Voil� donc, amaury pouly tu parles de r�sultat ind�termin� ? Je ne comprends pas... j'aimerais bien que tu m'expliques pourquoi mon code est horrible pour le corriger ? Pour ce qui est de la m�moire j'utiliserais gmp s'il le faut.

    Salut M�dinoc, en parlant de tableaux d'octets qu'est-ce que tu veux dire exactement ? Il me semblait que "buffer" dans mon code aggissait d�j� en tant que tel, ce n'est pas le cas ? Surtout que comme le dis dis reptils (salut au passage), je ne tra�te pas forc�ment du texte mais aussi bien des images, des octets de tout type en bref ! Et pour enfoncer le clou, j'ai fais une op�ration compl�te (� savoir chiffrer puis d�chiffrer) et j'ai obtenu avec du texte, le texte de d�part (test� avec un md5sum). Je ne vois pas o� des \0 auraient pu intervenir dans mon fichier vu qu'il est lu binairement (ios::binary ?).

    Sinon je pensais r�gler ce probl�me de cl� binaire en l'�crivant directement en binaire dans le code, �a pourrait jouer non ? Du style :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    char *key = "\x9cdfb439c7876e703e307864c9167a15";
    J'ai essay� comme �a, mais je ne sais pas si c'est le r�sultat esp�r�? C'est � dire que 9cd... soit pris comme du hex directement et convertit en binaire derri�re ? Enfin bon je viens de regarder dans mon manuel et apparemment �a fonctionne que pour \xhhh (3 chiffre hex donc). Dommage !

    Merci pour votre aide !

  16. #16
    Membre tr�s actif
    Avatar de buggen25
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Ao�t 2008
    Messages
    554
    D�tails du profil
    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels
    Secteur : Communication - M�dias

    Informations forums :
    Inscription : Ao�t 2008
    Messages : 554
    Par d�faut
    Pour le XOR (^) bit a bit
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     0101
    XOR
     0111
    =
     0010
    XOR
     0111
    ------
     0101 ---> donnée de départ
    Normalement c'est comme �a que �a marche, peut importe le type de donn�es qu'on manipule.

  17. #17
    Membre �prouv� Avatar de amaury pouly
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    157
    D�tails du profil
    Informations personnelles :
    �ge : 36
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 157
    Par d�faut
    Utiliser des doubles c'est horrible si on a besoin de pr�cision tout simplement parce qu'il y a des arrondis � toutes les �tapes. D'une part, entre deux machines diff�rentes, si par malheur le mode d'arrondis n'est pas le m�me, les r�sultats d'un MEME calcul peuvent �tre(et seront probablement) diff�rent. D'autre part, en flottant, aucune op�ration n'est associative(m�me pas + ), donc si par malheur deux compilos compilent le code diff�remment(notamment avec des optimisation), le code g�n�r� sera diff�rent donc le r�sultat aussi.
    Bref les doubles �a ne s'utilisent que pour des calculs approch�s

  18. #18
    Membre confirm�
    Profil pro
    Inscrit en
    Ao�t 2004
    Messages
    152
    D�tails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 152
    Par d�faut
    Merci pour vos conseils,

    Je pense avoir r�ussi � obtenir ce que je voulais. C'est � dire que ma cl� est convertie en nombre qui est inscrit donc en byte dans la m�moire. Ma cl� une fois convertie en d�cimal est "208521104953385306818825064957145938528". C'est bien l'ordre de grandeur attendu. J'ai fais tout mes tests tout semble marcher.

    Maintenant c'est est-ce que l'op�ration XOR fonctionne comme je le voudrais ? C'est � dire que qu'il fait bien un XOR sur les bits de ma cl� sur ceux des donn�es. Voici la derni�re version de mon code :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    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
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    #include <cstdlib>
    #include <iostream>
    #include <fstream>
    #include <math.h>
    #include <gmpxx.h>
     
    using namespace std;
     
    // Chiffrage
    // -- selon une clé char
    void crypt(char *text, int length, char *key, char *crypted) {
         int j = 0;
         for (int i = 0; i < length; i++) {
             // Lis la clé en boucle
             if (i%strlen(key) == 0) {
                   j=0;
             }
             // XOR
             crypted[i] = text[i] ^ key[j];
             j++;
         }
    }
     
    // -- selon une clé en binary mpz_class
    void crypt(char *text, int length, mpz_class key, char *crypted) {
         int j = 0;
         // Met dans un string (nombre base 10) le grand nombre
         // pour être utilisé lors du XOR
         string keychar = key.get_str(10);
         cout << keychar << endl;
         //const char *keychar = keystring.c_str();
         //sprintf(keychar, "%39.0i", key);
         for (int i = 0; i < length; i++) {
             // Lis la clé en boucle
             if (i%keychar.length() == 0) {
                   j=0;
             }
             // XOR
             crypted[i] = text[i] ^ keychar[j];
             j++;
         }
    }
     
    // Puissance avec des mpz_class
    mpz_class gmppow(mpz_class X, mpz_class Y) {
        mpz_class final=X;
        for (mpz_class i=1; i < Y; i++) {
            final = final*X;
        }
        return final;
    }
     
    // Conversion d'un char hex en mpz_class (int donc binaire)
    mpz_class convert_key_binary(char *key) {
         mpz_class result;
         result = 0;
         for (unsigned int i = 0; i < strlen(key); i++) {
             mpz_class tmp;
             // On lit de droite à gauche (inverser)
             char car = key[ i ];
             switch ( car ) {
                    case '0': tmp = 0; break;
                    case '1': tmp = 1; break;
                    case '2': tmp = 2; break;
                    case '3': tmp = 3; break;
                    case '4': tmp = 4; break;
                    case '5': tmp = 5; break;
                    case '6': tmp = 6; break;
                    case '7': tmp = 7; break;
                    case '8': tmp = 8; break;
                    case '9': tmp = 9; break;
                    case 'a': tmp = 10; break;
                    case 'b': tmp = 11; break;
                    case 'c': tmp = 12; break;
                    case 'd': tmp = 13; break;
                    case 'e': tmp = 14; break;
                    case 'f': tmp = 15; break;
                    default : cout << "Error"; return 0;
             }
             // Aditionne selon la règle de la position car*(16^pos)
             result += tmp*( gmppow(mpz_class(16), ((strlen(key)-1)-i)) );
         }
         return result;
    }
     
    int main(int argc, char *argv[])
    {
        // Prend en paramètre fichier src, fichier dst
        if (argc != 3) {
             cout << "Usage: " << argv[0] << " <fichier src> <fichier dst>" << endl;
             system("PAUSE");
             return 0;
        }
        else {
             cout << "Fichier d'entree: \t" << argv[1] << endl;
             cout << "Fichier en sortie: \t" << argv[2] << endl;
        }
        char *filename_in = argv[1];
        char *filename_out = argv[2];
     
        // Ouverture des fichiers
        fstream file_in(filename_in, ios::in|ios::binary);
        fstream file_out(filename_out, ios::out|ios::binary);
        if (!file_in || !file_out) {
              cout << "Impossible d'ouvrir !";
              system("PAUSE");
              return 0;
        }
     
        // Clé en char hex
        //char *key = "9cdfb439c7876e703e307864c9167a15";
        string keyString;
        cout << "Entrez la clef de chiffrage: ";
        getline(cin, keyString);
        char *key = (char *) keyString.c_str();
        int tmplen = strlen(key);
        // Teste si la longueur est puissance de 2
        if ( ((tmplen & -tmplen) xor tmplen) != 0 ) {
              cout << "La longueur de la cle doit etre une puissance de 2." << endl;
              system("PAUSE");
              return 0;
        }
     
        // Convertit la clé en binaire gros int (mpz_class)
        mpz_class keyhex = convert_key_binary(key);
        cout << keyhex << endl;
     
        // Variable de lecture
        int iter = 0;
        const int tranche = 192;
        char buffer[tranche];
     
        // Determine la longueur du fichier
        file_in.seekg(0, ios::end);
        int file_inlength = file_in.tellg();
        file_in.seekg(0, ios::beg);
     
        // Lis par tranche de tranche octets
        while (iter*tranche < file_inlength) {
              // Octet actuel
              int readByte;
              readByte = tranche;
              // Faut-il reduire la tranche de read/write
              if (iter*tranche+tranche > file_inlength)
                 readByte = file_inlength-iter*tranche;
              strcpy(buffer, "");
              // Lis une tranche d'octets, chiffre et écrit
              file_in.read(buffer, readByte);
              char tmp[readByte];
              crypt(buffer, readByte, keyhex, tmp);
              file_out.write(tmp, readByte);
              iter++;
        }
     
        // Ferme les fichiers
        file_in.close();
        file_out.close();
     
        cout << "\nFini\n";
        system("PAUSE");
        return 0;
    }
    L'op�ration xor entre un string et un char se passe-t-elle comme entre char (tableau binaire) ? C'est tr�s important que ce soit bien une cl� 128 bits qui soit utilis� et non la cha�ne en char, pour des raisons �videntes: que ce soit universel avec d'autres chiffreur XOR (peut-�tre aurait-je � faire le m�me type dans un autre langage).

    Merci beaucoup.

  19. #19
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par d�faut
    pour d�finir ta cl�, tu peux la d�finir de la mani�re suivante :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    unsigned char key[16] = { 0x9c, 0xdf, 0xb4, 0x39, 0xc7, 0x87, 0x6e, 0x70, 0x3e, 0x30, 0x78, 0x64, 0xc9, 0x16, 0x7a, 0x15 };
    Pour le xor, tu peux le faire octet par octet, en parcourant ta cl� et le fichier en parrall�le.

    Tu ne dois pas utiliser les fonctions sur les cha�nes de caract�res (strlen et consorts), car tu ne travaille pas avec des cha�nes de caract�res. La bonne solution, c'est de passer la taille de ta cl� � ta fonction crypt.

    Enfin, je ne sais pas dans quel contexte tu comptes utiliser cela, mais ce cryptage n'est pas fiable du tout pour un grand texte et une petite cl�.

  20. #20
    Membre confirm�
    Profil pro
    Inscrit en
    Ao�t 2004
    Messages
    152
    D�tails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 152
    Par d�faut
    Citation Envoy� par white_tentacle Voir le message
    pour d�finir ta cl�, tu peux la d�finir de la mani�re suivante :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    unsigned char key[16] = { 0x9c, 0xdf, 0xb4, 0x39, 0xc7, 0x87, 0x6e, 0x70, 0x3e, 0x30, 0x78, 0x64, 0xc9, 0x16, 0x7a, 0x15 };
    Merci bien ! Je ne connaissais pas. Il y a moyen d'utiliser cette d�finition avec une cl� entr�e au clavier avec getline() ?

    Citation Envoy� par white_tentacle Voir le message
    Pour le xor, tu peux le faire octet par octet, en parcourant ta cl� et le fichier en parrall�le.
    Je pensais que mon code faisait octet par octet ! C'est pas le cas de cette boucle for ici ? :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // -- selon une clé en binary mpz_class
    void crypt(char *text, int length, mpz_class key, char *crypted) {
         int j = 0;
         // Met dans un string (nombre base 10) le grand nombre
         // pour être utilisé lors du XOR
         string keychar = key.get_str(10);
         cout << keychar << endl;
         //const char *keychar = keystring.c_str();
         //sprintf(keychar, "%39.0i", key);
         for (int i = 0; i < length; i++) { // <== ICI boucle octet par octet ?
             // Lis la clé en boucle
             if (i%keychar.length() == 0) {
                   j=0;
             }
             // XOR
             crypted[i] = text[i] ^ keychar[j]; // <== ICI 1 octet ^ 1 octet non ?
             j++;
         }
    }
    Citation Envoy� par white_tentacle Voir le message
    Tu ne dois pas utiliser les fonctions sur les cha�nes de caract�res (strlen et consorts), car tu ne travaille pas avec des cha�nes de caract�res. La bonne solution, c'est de passer la taille de ta cl� � ta fonction crypt.
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    void crypt(char *text, int length, mpz_class key, char *crypted) {
    [...]
     
             // Lis la clé en boucle
             if (i%keychar.length() == 0) { // <-- ICI je ne devrais pas utiliser length ???
    Comme je l'ai dis, � cause du typage je suis oblig� de convertir mon grand nombre stock� dans key en un string, sinon le XOR ne passe pas (probl�me de typage, non compatible). C'est peut-�tre inadapt� mais j'ai pas trouv� mieux

    Citation Envoy� par white_tentacle Voir le message
    Enfin, je ne sais pas dans quel contexte tu comptes utiliser cela, mais ce cryptage n'est pas fiable du tout pour un grand texte et une petite cl�.
    Dans un contexte o� les donn�es doivent �tre proteg�es � ce que les gens normaux n'y acc�dent pas. Je parle d'utilisateur lambda voir peut-�tre plus. Donc je pense qu'un tel chiffrage est bien suffisant. Je ne pense pas tomber sur des crackers ou autres professionnels du d�chiffrage parce que les donn�es n'ont pas beaucoup de valeurs, elles ne sont pas confidentiels. C'est simplement qu'il a fallu du travail pour r�unir ces informations et le chiffrer me semble une bonne m�thode afin d'emp�cher n'importe qui d'y acc�der sans le programme. Rien de plus.

    J'aimerais bien avoir quelques commentaires si mon code afin de l'am�liorer et, moi, pour apprendre. J'ai l'impression que vous fa�te des commentaires mais sans jeter un oeil au code, d�sol� si je me trompe. J'ai vraiment envie de progresser et je suis s�r que il y a pleins de choses � corriger qui vous semble �vidente dans mon code.

    Merci � vous.

+ R�pondre � la discussion
Cette discussion est r�solue.
Page 1 sur 2 12 Derni�reDerni�re

Discussions similaires

  1. parser un fichier avec xerces
    Par traiangueul dans le forum XML/XSL et SOAP
    R�ponses: 9
    Dernier message: 02/02/2004, 18h14
  2. R�ponses: 8
    Dernier message: 14/11/2003, 22h51
  3. Dossier ou Fichier avec ShellListView
    Par MoussDiouf dans le forum Langage
    R�ponses: 6
    Dernier message: 14/06/2003, 12h33
  4. [VB6] [Réseau] Récupérer la taille d'un fichier avec inet
    Par pcpunch dans le forum VB 6 et ant�rieur
    R�ponses: 11
    Dernier message: 20/02/2003, 21h38
  5. enregistrer dans un fichier avec une appli mdi
    Par ferrari dans le forum C++Builder
    R�ponses: 4
    Dernier message: 05/05/2002, 15h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo