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

Langage Delphi Discussion :

Crypter un fichier byte par byte


Sujet :

Langage Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Inscrit en
    Octobre 2004
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 5
    Par défaut Crypter un fichier byte par byte
    Bonjour,

    J'ai besoin de crypter un fichier byte par byte.
    Existe-t-il une API Windows qui permet de faire ceci ?
    Si non, merci de m'indiquer comment procéder.

  2. #2
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 173
    Billets dans le blog
    9
    Par défaut
    Bonjour !

    En faisant des recherches avec les mots-clés "Crypt API Delphi", on trouve pas mal de choses, par exemple cette page.

    Autrement, Paul TOTH avait posté une simple procédure qui peut peut-être vous suffire.

  3. #3
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 173
    Billets dans le blog
    9
    Par défaut
    En m'inspirant d'un autre exemple de Paul TOTH, je me suis amusé à faire quelque chose. J'espère que vous ne verrez pas d'inconvénient à ce que je le propose ici.

    L'idée était donc de faire un tableau de conversion, comme dans l'exemple. Chaque caractère est associé (de façon aléatoire) à un unique autre caractère. Un deuxième tableau permet de revenir au caractère initial. Le code source est fabriqué par un programme. Les tables générées sont à chaque fois différentes.

    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
     
    program MakeTables;
     
    {$APPTYPE CONSOLE}
     
    uses
      SysUtils;
     
    var
      a, b: array[byte]of byte;
      i, r: integer;
      s: string;
      t: textfile;
     
    begin
    { Associer à chaque nombre de 0 à 255 un unique autre nombre du même intervalle.
      Remplir une deuxième table qui permette de retrouver le premier nombre à
      partir du second. }
     
      Randomize;
     
    { Les nombres de 0 à 255 sont placés dans une chaîne, afin qu'on puisse les
      prélever. Les nombres sont écrits sous la forme hexadécimale. }
     
      for i := 0 to 255 do
        s := s + IntToHex(i, 2);
     
      for i := 0 to 255 do
      begin
    { On prend au hasard dans la chaîne. }
        r := Random(Length(s) div 2);
    { Le nombre est copié dans le tableau. }
        a[i] := StrToInt('$' + Copy(s, 2 * r + 1, 2));
    { On retire le nombre de la chaîne. }
        Delete(s, 2 * r + 1, 2);
      end;
     
      Assert(Length(s) = 0);
     
    { On remplit la deuxième table. }
      for i := 0 to 255 do
        b[a[i]] := i;
     
    { On fabrique le code source. }
      AssignFile(t, 'Tables.pas');
      Rewrite(t);
     
      WriteLn(t);
      WriteLn(t, 'unit Tables;');
      WriteLn(t);
      WriteLn(t, 'interface');
      WriteLn(t);
      WriteLn(t, 'const T1: array[char]of char =');
     
      for i := 0 to 255 do
        s := s + '#' + Format('%.*d', [3, a[i]]);
     
      for i := 1 to 15 do
        WriteLn(t, Copy(s, 64 * (i - 1) + 1, 64) + '+');
      WriteLn(t, Copy(s, 64 * (16 - 1) + 1, 64) + ';');
     
      WriteLn(t);
      WriteLn(t, 'const T2: array[char]of char =');
     
      SetLength(s, 0);
     
      for i := 0 to 255 do
        s := s + '#' + Format('%.*d', [3, b[i]]);
     
      for i := 1 to 15 do
        WriteLn(t, Copy(s, 64 * (i - 1) + 1, 64) + '+');
      WriteLn(t, Copy(s, 64 * (i - 1) + 1, 64) + ';');
     
      WriteLn(t);
      WriteLn(t, 'implementation');
      WriteLn(t);
      WriteLn(t, 'end.');
      WriteLn(t);
     
      CloseFile(t);
     
      WriteLn('FIN');
      ReadLn;
    end.
    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
     
    unit Crypt;
     
    interface
     
    function Encrypt(const s: ansistring): ansistring;
    function Decrypt(const s: ansistring): ansistring;
    procedure EncryptFile(const aFilename, aNewFilename: string);
    procedure DecryptFile(const aFilename, aNewFilename: string);
     
    implementation
     
    uses
      Tables;
     
    function Encrypt(const s: ansistring): ansistring;
    var
      i: integer;
    begin
      SetLength(result, Length(s));
      for i := 1 to Length(result) do
        result[i] := T1[s[i]];
    end;
     
    function Decrypt(const s: ansistring): ansistring;
    var
      i: integer;
    begin
      SetLength(result, Length(s));
      for i := 1 to Length(result) do
        result[i] := T2[s[i]];
    end;
     
    procedure EncryptFile(const aFilename, aNewFilename: string);
    var
      f: file;
      s: ansistring;
      sz: integer;
    begin
      Assign(f, aFilename);
      Reset(f, 1);
      sz := FileSize(f);
      SetLength(s, sz);
      BlockRead(f, s[1], sz);
      Close(f);
     
      s := Encrypt(s);
     
      Assign(f, aNewFilename);
      Rewrite(f, 1);
      BlockWrite(f, s[1], sz);
      Close(f);
    end;
     
    procedure DecryptFile(const aFilename, aNewFilename: string);
    var
      f: file;
      s: ansistring;
      sz: integer;
    begin
      Assign(f, aFilename);
      Reset(f, 1);
      sz := FileSize(f);
      SetLength(s, sz);
      BlockRead(f, s[1], sz);
      Close(f);
     
      s := Decrypt(s);
     
      Assign(f, aNewFilename);
      Rewrite(f, 1);
      BlockWrite(f, s[1], sz);
      Close(f);
    end;
     
    end.
    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
    program Test1;
     
    {$APPTYPE CONSOLE}
     
    uses
      Crypt;
     
    var
      s: ansistring;
     
    begin
      s := 'Essai chiffrement-déchiffrement';
      s := Encrypt(s);
      s := Decrypt(s);
      WriteLn(s);
      Write('ENTREE');
      ReadLn;
    end.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    program Test2;
     
    {$APPTYPE CONSOLE}
     
    uses
      Crypt;
     
    begin
      EncryptFile('readme.indy.txt', 'encrypted.txt');
      DecryptFile('encrypted.txt', 'decrypted.txt');
    end.
    [EDIT]
    Ajouté les fonctions EncryptFile et DecryptFile. Remplacé les types string et char par ansistring et ansichar. Le programme a été testé avec Delphi 7 et Delphi XE2.
    [/EDIT]

  4. #4
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 173
    Billets dans le blog
    9
    Par défaut
    J'ai testé avec succès l'exemple WinCrypt de Bernd Lehmann. Quoique le code soit de 1999, j'ai pu le compiler avec Delphi 7 et le test que j'ai fait sur un fichier texte a réussi.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (* http://www.efg2.com/Lab/Library/Delphi/MathFunctions/BerndLehmannCrypto.zip *)

  5. #5
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Par défaut
    Bonjour,

    Juste une première remarque : Dans l'unit Crypt on trouve result[i] := T1[s[i]] et result[i] := T2[s[i]] mais on n'y trouve pas la déclaration de T1 et T2.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  6. #6
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 173
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Juste une première remarque : Dans l'unit Crypt on trouve result[i] := T1[s[i]] et result[i] := T2[s[i]] mais on n'y trouve pas la déclaration de T1 et T2.
    Bonjour ! Merci pour la réponse. Les tables T1 et T2 se trouvent dans l'unité Tables, qui est générée par le programme MakeTables. A chaque exécution les tables générées sont différentes. Voilà pourquoi je n'ai pas joint le code mais pour la clarté de la discussion il vaut peut-être mieux que je l'ajoute.

    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
     
    unit Tables;
     
    interface
     
    const T1: array[ansichar]of ansichar =
    #037#068#074#096#065#021#130#201#222#251#207#103#199#102#052#192+
    #088#240#016#069#044#097#026#193#093#153#060#119#196#159#070#253+
    #172#174#135#104#225#019#231#254#227#110#003#198#015#054#080#180+
    #150#053#092#219#181#186#187#141#202#244#049#197#210#245#255#137+
    #168#229#132#009#057#173#228#146#206#014#177#004#035#175#126#167+
    #091#050#116#117#216#169#062#079#241#101#124#048#230#223#182#208+
    #136#028#034#195#125#040#118#224#247#226#162#042#077#212#105#011+
    #084#142#108#164#100#194#055#085#046#024#213#179#178#094#109#235+
    #171#236#030#214#161#215#076#152#056#188#018#149#058#038#211#036+
    #061#081#067#221#017#165#248#120#128#025#095#140#098#031#051#239+
    #166#064#047#059#154#066#217#063#020#121#147#001#233#246#189#113+
    #218#220#238#027#087#073#114#000#106#112#185#043#071#123#133#007+
    #013#138#010#160#249#252#023#129#156#145#083#039#143#006#115#075+
    #029#005#090#131#151#134#107#204#234#203#022#144#002#078#191#127+
    #163#122#089#184#041#237#243#183#139#176#200#072#209#242#032#250+
    #205#232#045#082#157#086#008#033#158#012#190#111#155#099#170#148;
     
    const T2: array[ansichar]of ansichar =
    #183#171#220#042#075#209#205#191#246#067#194#111#249#192#073#044+
    #018#148#138#037#168#005#218#198#121#153#022#179#097#208#130#157+
    #238#247#098#076#143#000#141#203#101#228#107#187#020#242#120#162+
    #091#058#081#158#014#049#045#118#136#068#140#163#026#144#086#167+
    #161#004#165#146#001#019#030#188#235#181#002#207#134#108#221#087+
    #046#145#243#202#112#119#245#180#016#226#210#080#050#024#125#154+
    #003#021#156#253#116#089#013#011#035#110#184#214#114#126#041#251+
    #185#175#182#206#082#083#102#027#151#169#225#189#090#100#078#223+
    #152#199#006#211#066#190#213#034#096#063#193#232#155#055#113#204+
    #219#201#071#170#255#139#048#212#135#025#164#252#200#244#248#029+
    #195#132#106#224#115#149#160#079#064#085#254#128#032#069#033#077+
    #233#074#124#123#047#052#094#231#227#186#053#054#137#174#250#222+
    #015#023#117#099#028#059#043#012#234#007#056#217#215#240#072#010+
    #095#236#060#142#109#122#131#133#084#166#176#051#177#147#008#093+
    #103#036#105#040#070#065#092#038#241#172#216#127#129#229#178#159+
    #017#088#237#230#057#061#173#104#150#196#239#009#197#031#039#062;
     
    implementation
     
    end.
    J'aimerais bien savoir ce que vous pensez de ce programme, ou si vous avez des améliorations à suggérer.

  7. #7
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Par défaut
    Re-bonjour,

    Je retire ce que je viens de dire : les constantes T1 et T2 sont créées dans le fichier Tables.pas : un peu compliqué.

    Autre remarque : il s'agit d'un simple cryptage par substitution et d'après la littérature facile à casser (par exemple, ShaiLeTroll écrit ici le 04/01/2012, 11h45 :http://www.developpez.net/forums/d11...e/#post6428544
    Dans une simple substitution de l'alphabet, une analyse statistique permet de retrouver les lettres les plus utilisées, si l'on connait la langue du texte, il est facile de retrouver le e pour le français et les autres lettres et de casser l'Alphabet utilisé pour la substitution !
    Si en plus un hacker combine l'analyse statistique avec la recherche d'un mot probable et répété ça lui facilite encore davantage la vie.

    Pour ma part j'aime bien le cryptage par la méthode Vigénère vu les avantages suivants :
    a) Une même lettre est codée par des lettres différentes selon sa position dans le texte : rend inutilisable l'attaque par analyse de fréquence directe.

    b) Attaque par mot probable : Nécessite que la longueur du mot probable soit supérieure ou égale à celle de la clé. Dans le français aucun mot probable ne dépasse 52 lettres :
    - français courant : anticonstitutionnellement : 25 lettres.
    - chimie : chlorure d'aminométhylpyrimidinyl-hydroxy-éthylméthy-thiazolium : 52 lettres.
    Donc avec une clé de 26 ou 53 lettres, selon le contenu du texte en clair, cette attaque devient impossible puisque le texte en clair est formé de mots plus courts.

    c) Attaque par brute-force en connaissant la longueur de la clé : Le nombre de clefs possibles est très grand même si la longueur de celle choisie est relativement courte.
    Exemple, pour une clé de 13 lettres il y a 26 choix pour la première lettre, 26 choix pour la seconde lettre, etc... soit au total 26^13 = 2 481 152 873 203 736 576 choix possibles.
    Un ordinateur essayant un million de clés par seconde mettrait 78 623 années pour toutes les essayer.
    Et pour une clé de 26 lettres : 26^26 = 6 156 119 580 207 157 310 796 674 288 400 203 776 choix possibles => 195 075 657 851 267 438 296 850 années pour hacker.
    Impossible de décrypter si on ne connaît pas la longueur de la clé, et même avec une seule et unique clé de longueur connue de 26 lettres on est tranquille pendant des milliards d'années en attendant les ordis quantiques.

    Voici un bout de code pour la méthode Vigenère :
    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
    function CodeDecVigenere(S, Clef: tMemoryStream; Coder: Boolean): tMemoryStream; 
    // S = texte à crypter/décrypter
    // Clef = Clef de cryptage/décryptage
    // Si Coder = True alors Result = texte crypté sinon Result = texte décrypté.
    var i, LClef, poClef: Cardinal; Sens: smallint; ps, pc, pcd, pr: PByte;
     
      function Trans(Ch1, Ch2: byte; Sens: smallint): byte;
      var r: integer;
      begin
        r := (Ch1 + Ch2 * sens);
        if r > 255 then r := r - 256;
        if r < 0 then r := 256 + r;
        Result := r;
      end;
     
    begin
      Result := tMemoryStream.Create; Result.Position := 0; Result.SetSize(S.Size);
      ps := S.Memory; pc := Clef.Memory; pcd := pc; pr := Result.Memory;
      poClef := 0;
      if (Clef.Size <> 0) and (S.Size <> 0) then begin
        Lclef := Clef.Size;
        if Coder then Sens := -1 else Sens := +1;
        for I := 0 to S.Size - 1 do begin
          if poClef = Lclef then begin pc := pcd; poClef := 0; end; // Clef.Position := 0;
          pr^ := Trans(ps^, pc^, Sens);
          inc(ps); inc(pc); inc(pr); inc(poClef);
        end;
      end;
    end;
    Pour utiliser, il suffit d'utiliser :
    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
    var BufMess, BufCleVig: TMemoryStream;
     
    procedure StrToStream(Stream: TStream; Chaine: string);
    var i: integer; c: char;
    begin
      if length(Chaine) > 0 then
        for i := 1 to length(Chaine) do begin
          c := Chaine[i];
          stream.Write(c, 1);
        end;
      c := #0;
      stream.Write(c, 1);
    end;
     
    // Lors du chargement depuis le disque du fichier à crypter/décrypter:
      ...
      BufMess := TMemoryStream.Create;
      BufMess.LoadFromFile(FileName); // fichier à crypter/décrypter
      BufCleVig := TMemoryStream.Create;
      StrToStream(BufCleVig, edClefVigenere.Text); // la clef
      ...
    // Pour le cryptage :
      ...
      BufMess.Position := 0; BufCleVig.Position := 0;
      BufMess := CodeDecVigenere(BufMess, BufCleVig, TRUE); 
      ...
    // Pour le décryptage:
      ...
      BufMess.Position := 0; BufCle.Position := 0;
      BufMess := CodeDecVigenere(BufMess, BufCleVig, FALSE);
      ...
    // Pour afficher les résultats dans un RichEdit :
      ...
      RichEdit2.Lines.BeginUpdate;
      BufMess.Position := 0; 
      RichEdit2.Lines.LoadFromStream(BufMess);
      RichEdit2.Lines.EndUpdate;
      BufMess.Free; BufCleVig.Free; 
      ...
    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

Discussions similaires

  1. Crypter un fichier byte à byte : Epilogue 2
    Par Rekin85 dans le forum Contribuez
    Réponses: 11
    Dernier message: 30/10/2014, 13h41
  2. Lire byte par byte avec QHttp
    Par looclooc dans le forum Débuter
    Réponses: 1
    Dernier message: 04/08/2009, 08h17
  3. Fichier image to Byte[]
    Par Mengué georges dans le forum Langage
    Réponses: 2
    Dernier message: 10/06/2009, 20h43
  4. Lecture fichier, retour en byte[]
    Par ArnaudDev dans le forum Général JavaScript
    Réponses: 0
    Dernier message: 20/04/2009, 16h14
  5. [VB.NET] Fichier text et byte()
    Par nmerydem dans le forum Windows Forms
    Réponses: 6
    Dernier message: 10/11/2004, 17h28

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