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

  1. #1
    Candidat au Club
    Inscrit en
    Octobre 2004
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 5
    Points : 4
    Points
    4
    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 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 457
    Points
    15 457
    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.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  3. #3
    Rédacteur/Modérateur

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

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 457
    Points
    15 457
    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]
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  4. #4
    Rédacteur/Modérateur

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

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 457
    Points
    15 457
    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 *)
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  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
    Points : 3 263
    Points
    3 263
    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 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 457
    Points
    15 457
    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.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  7. #7
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 857
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 857
    Points : 11 291
    Points
    11 291
    Billets dans le blog
    6
    Par défaut
    Bonjour Roland,

    C'est simple et efficace, mais oblige à transmettre in extenso le tableau de (dé)cryptage avec le fichier crypté.

    Ne pourrait-on prévoir une procédure qui les générerait à partir d'un simple mot de passe, que l'on peut transmettre à part plus commodément ?
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  8. #8
    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
    Points : 3 263
    Points
    3 263
    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

  9. #9
    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
    Points : 3 263
    Points
    3 263
    Par défaut
    Re-salut,

    Oups : je n'avais pas remarqué que pendant que je rédigeais vos eux messages se sont intercalés : je suis trop lent.

    Roland Chastain :
    J'aimerais bien savoir ce que vous pensez de ce programme, ou si vous avez des améliorations à suggérer.
    Je préfère personnellement la méthode Vigenère vu que le cryptage par substitution est réputé "facile à casser" (bien que je n'ai jamais essayé d'en casser un).
    Par contre pour améliorer, au lieu d'utiliser des constantes T1, T2 de surcroît planquées dans une unité, je remplacerais ceci volontiers dans var T1,T2: array[ansichar] of ansichar et je supprimerais l'unit Tables.pas.

    Tourlourou :
    C'est simple et efficace, mais oblige à transmettre in extenso le tableau de (dé)cryptage avec le fichier crypté.
    Ne pourrait-on prévoir une procédure qui les générerait à partir d'un simple mot de passe, que l'on peut transmettre à part plus commodément ?
    Comme T2 est la table de décryptage il suffit de la transformer en une ansistring de 256 caractères et de l'insérer à la position Po dans l'ansistring du texte crypté qu'on envoie au destinataire et le mot de passe devient Po.
    A la réception du message le destinataire saura qu'avant de décrypter il lui faut d'abord lire puis supprimer l'ansistring des 256 à la positio Po.
    La valeur de Po peut être transmise au destinataire par un autre canal de communication lors d'une communication confidentielle lors de laquelle il n'est pronononcé qu'un seul nombre.

    A+.

    EDIT A propos du "et le mot de passe devient Po" ci-dessus : En fait pour une clef de décryptage embarquée le mot de passe en nécessite deux, le premier c'est Po et le second c'est la longueur de la clef (256 dans le cas particulier de la substitution, mais variable dans le cas des autres algos)
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  10. #10
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 857
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 857
    Points : 11 291
    Points
    11 291
    Billets dans le blog
    6
    Par défaut
    On peut effectivement masquer la table dans le fichier, mais ce sera probablement la seule suite de 256 caractères à tous les contenir, et reste la possibilité d'attaque en fréquence.

    Reste à part un point théorique : existe-t-il des API pour lire/écrire à position aléatoire dans un fichier existant (il faut alors j'imagine tenir compte de la position du caractère dans le fichier) plutôt que lire - décrypter - manipuler - encrypter - écrire tout le fichier ? Ces méthodes pourraient-elles être solides ?
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  11. #11
    Rédacteur/Modérateur

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

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 457
    Points
    15 457
    Billets dans le blog
    9
    Par défaut
    @Gilbert Geyer
    @tourlourou

    Merci pour vos observations. (Je vais me pencher sur le "Vigenère".)

    J'aime bien l'idée d'inclure la clé dans le message à telle position (tout en reconnaissant la justesse de la remarque de tourlourou).

    Ce qui m'avait intéressé entre autres en faisant ce petit programme, c'était le problème qui consiste à associer à chaque nombre de 0 à 255 un unique autre nombre du même intervalle. Je m'en suis sorti avec une chaîne mais ça fait peut-être un peu bricolage. Je m'amuse pas mal ces temps-ci avec Lua, qui permet de faire très simplement ce genre de choses. Mais tout cela nous éloigne du sujet de cette discussion...
    Fichiers attachés Fichiers attachés
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  12. #12
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 857
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 857
    Points : 11 291
    Points
    11 291
    Billets dans le blog
    6
    Par défaut
    Ma remarque n'est pas si juste : rien n'oblige à l'insérer d'un bloc, ni dans l'ordre...

    La solidité d'un cryptage (outre les problèmes de méthodes soulevés) repose sûrement sur un algorithme privé suffisamment complexe ou un algorithme public avec clef suffisamment puissante.

    Pour les besoins de l'amateur et en petit cercle, rien de tel qu'un algorithme bien privé ou une solution publique bien éprouvée !
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  13. #13
    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
    Points : 3 263
    Points
    3 263
    Par défaut
    Re-salut,

    tourlourou :
    La solidité d'un cryptage (outre les problèmes de méthodes soulevés) repose sûrement sur un algorithme privé suffisamment complexe ou un algorithme public avec clef suffisamment puissante.
    Pour les besoins de l'amateur et en petit cercle, rien de tel qu'un algorithme bien privé ou une solution publique bien éprouvée !
    Globalement d'accord, par contre pour les algos privés je suis persuadé qu'il n'est pas indispensable d'utiliser des trucs "complexes" car on peut utiliser par exemple 2 à 3 algos simples A1, A2 et A3 et le texte crypté avec A1, on le sur-crypte avec A2 et le résultat du sur-cryptage on le sur-crypte avec A3.
    Déjà en n'utilisant que A1 = cryptage par substitution et A2 = cryptage XOR (méthode Paul TOTH citée en début de discussion) on complique déjà bien la vie à un Hacker.
    Car si le Hacker tombe par hasard sur la bonne combinaison de paramètres de la méthode A1 il se retrouve avec un texte qui reste crypté avec la méthode 2 et du coup il ne peut être conscient qu'il a trouvé les bons paramètres de la méthode A1 et idem s'il trouve les bons paramètres de la méthode A2.
    En plus de ceci il est impossible de décrypter un texte sur-crypté si on ne sait pas :
    - qu'il est sur-crypté,
    - avec quel nombre d'algos,
    - avec quels algos simples,
    - et dans quel ordre ces algos ont été utilisés pour crypter, car pour dé-crypter il faut utiliser les algos dans l'ordre inverse.

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

  14. #14
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 857
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 857
    Points : 11 291
    Points
    11 291
    Billets dans le blog
    6
    Par défaut
    Bonjour Gilbert,

    Je suis d'accord avec toi : plusieurs couches ça protège mieux !
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  15. #15
    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
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Juste une remarque pour combler un oubli à propos de :
    Valochette : Crypter un fichier byte par byte
    et de :
    Roland Chastain : Je vais me pencher sur le "Vigenère".
    Il se trouve que l'utilisation de tMemoryStream dans la function CodeDecVigenere(S, Clef: tMemoryStream; Coder: Boolean): tMemoryStream permet de crypter aussi bien des fichiers de Texte que des fichiers Image et tout fichier de bytes. Bien entendu seuls les fichiers Texte peuvent être affichés dans un tRichEdit.
    Pour visualiser le résultat du décryptage d'un fichier autre que du texte il suffit de le sauver avec son extension d'origine et de l'ouvrir avec un logiciel approprié (ex : PaintShopPro si Image, Word si Texte avec Images, etc).

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

  16. #16
    Membre actif

    Homme Profil pro
    Inscrit en
    Mars 2009
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2009
    Messages : 128
    Points : 203
    Points
    203
    Par défaut
    Bonjour à tous surtout à Gilbert et Yves...

    Je ne peux laisser cette discussion sans y laisser mon petit grain de sel... Nous avons tellement travaillé, Gilbert et moi sur les types de cryptages...

    J'aime bien le vigénère, il fait "mystérieux" et a connu ses heures de gloires dans l'Histoire des messages cryptés, de César à Enigma. En plus, Gilbert, il est capable de l'utiliser en X couches de cryptages et sur-cryptages : imparable !

    Informatiquement parlant, la base du cryptage moderne est l'opération XOR qui a l'avantage d'être identique au cryptage et au décryptage. Alors les processus d'utilisations sont multiples suivant le degré d'astuce du programmeur : par blocs, par rotations, etc...

    On sait que le procédé totalement indéchiffrable est le Vernam intégral : Soit un message à crypter M de N octets. Si on prend un à un ses N octets à qui on fait subir un XOR avec pour chacun un octet généré aléatoirement (pas pseudo-aléatoirement !), on obtient un message M' de N octets totalement indéchiffrables si on ne possède pas les N octets aléatoires correspondants. Ce qui fait que l'on se trouve avec un procédé par clé de longueur égale au message lui-même... Bon lourd et avec une grosse faille si un intercepteur lambda sait quelle clé correspond au message M.

    Le Vernam peut se décliner en version plus simple surtout si on génère des pseudo-aléatoires avec une grande amplitude de redondance. Le générateur aura besoin d'une "graine" de démarrage qui deviendra donc la fameuse clé de cryptage... Ensuite, toutes les astuces sont imaginables pour :
    soit : extraire la graine du message lui-même
    soit : triturer les bits des octets-clés au cours de la xorisation
    soit : planquer la clé dans le crypté (ce qui oblige à posséder des routines privées pour l'y placer et l'y retrouver).

    Voir la discussion ici http://www.phidels.com/php/forum/for...&postid=125081

  17. #17
    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
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour à tous et salut René,

    Rekin85 : J'aime bien le Vigenère, il fait "mystérieux" et a connu ses heures de gloires dans l'Histoire des messages cryptés, de César à Enigma.
    On sait que le procédé totalement indéchiffrable est le Vernam intégral...
    Tu dis "mystérieux", pour moi c'est plutôt le Vernam que tu as tricoté en ASM qui m'est mystérieux (j'y pige que dalle)... mais efficace.

    A propos de :
    ... soit : planquer la clé dans le crypté (ce qui oblige à posséder des routines privées pour l'y placer et l'y retrouver).
    Bon, si Valochette a besoin de crypter un fichier pour le confier à un Cloud douteux il lui suffit de planquer sa clé de cryptage/dé-cryptage dans son disque dur sous le même nom que celui du fichier crypté et avec une extension différente pour la retrouver et l'utiliser pour le décryptage lors de la récupération du fichier depuis le Cloud. (il y a tellement d'arnaques sur le net qu'il vaut mieux prendre des précautions).

    Concernant les sur-cryptages : Ce que j'aime le plus avec les sur-cryptages c'est qu'ils pourrissent bigrement la vie aux Hackers les plus futés car même s'ils trouvent par hasard la bonne combinaison de paramètres qui décryptent l'une des couches du cryptage ils ne peuvent pas s'en rendre compte vu que le message reste crypté par les autres couches donc ils tournent en bourrique .

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

  18. #18
    Membre actif

    Homme Profil pro
    Inscrit en
    Mars 2009
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2009
    Messages : 128
    Points : 203
    Points
    203
    Par défaut Pour Gilbert
    Salut chaleureux à toi, Gilbert

    Depuis nos derniers échanges, je n'ai pratiquement rien fait sauf cette procedure :

    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
    // Crypte et copie un Tampon par un double Vernam avec Clé de 64 bits
    procedure CrypteEtCopy(Tp1,Tp2: pointer; Key: String; Size: longWord); register;
    var Al1,Al2 : longInt;
        procedure Alea1;
        asm
            xor     eax,eax
            dec     eax
            imul    edx,Al1,$08088405
            inc     edx
            mov     Al1,edx
            mul     edx
            mov     eax,edx
         end;
         procedure Alea2;
        asm
            xor     eax,eax
            dec     eax
            imul    edx,Al2,$08088405
            inc     edx
            mov     Al2,edx
            mul     edx
            mov     eax,edx
         end;
    asm
        push     esi
        mov      esi,eax
        push     edi
        mov      edi,edx
        mov      eax,Dword ptr[ecx]
        mov      Al1,eax
        mov      eax,Dword ptr[ecx+4] 
        mov      Al2,eax
        mov      ecx,[ebp]+$8
        push     ecx
        shr      ecx,$3
        jz       @Reste
        @XorQWords:
              call   Alea1
              mov    edx,DWord ptr[esi]
              xor    edx,eax
              mov    DWord ptr[edi],edx
              add    esi,$4
              add    edi,$4
              call   Alea2
              mov    edx,DWord ptr[esi]
              xor    edx,eax
              mov    DWord ptr[edi],edx
              add    esi,$4
              add    edi,$4
              loop   @XorQWords
        @Reste:
        pop      ecx
        and      ecx,$7
        jz       @Fin
        call     Alea1
        mov      edx,eax
        call     Alea2
        @XorBytes:
              xor    al,Byte ptr[esi]
              mov    Byte ptr[edi],al
              inc    esi
              inc    edi
              mov    al,dl
              shr    edx,$8
              ror    eax,$8
              loop   @XorBytes
        @Fin:
        pop      edi
        pop      esi
    end;
    Vernam toujours, sauf que là, la routine travaille en double 32 bits donc avec une clé de 64 bits. Ce n'est pas du sur-cryptage, mais du "faux" 64 bits... Le produit crypté est donc généré par deux générateurs pseudo-aléatoires de 32 bits en intercalés... du super filou comme dirait Yves

    Cette routine va donc "à la vitesse de la lumière" et pour crypter tout fichier que l'on veut, il faut lui fournir une string qui fait office de clé d'au moins 8 octets.

    Pour l'utiliser correctement:
    1/ Créer deux MemoryStream : TMem1 et TMem2 :=TMemoryStream.create;
    2/ Charger le fichier à crypter dans le premier : TMem1.loadfromfile(fic);
    3/ Dimensionner TMem2 à la meme taille : TMem2.SetSize(TMem1.Size);
    4/ créer une string (cle) d'au moins 8 octets : Cle:='chaîne quelconque';
    5/ Procéder au cryptage : CrypteEtCopy(TMem1.Memory,TMem2.Memory.Clé,TMem1.Size);
    6/ Sauver le crypté : TMem2.SaveToFile(Fic.Dat)

    et pour le décryptage, faire les mêmes opérations (crypté en TMem1) en prenant soin de "filer" la même clé qu'au cryptage... C'est joué, décrypté en TMem2 !

  19. #19
    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
    Points : 3 263
    Points
    3 263
    Par défaut
    Re-salut,

    Salut chaleureux à toi, René.
    Depuis nos derniers échanges, je n'ai pratiquement rien fait sauf cette procedure CrypteEtCopy(Tp1,Tp2: pointer; Key: String; Size: longWord); register
    Super!!! Cela va permettre d'ajouter une couche de sur-cryptage supplémentaire.
    Je la testerai demain vu l'heure.

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

  20. #20
    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
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    J'ai testé la procedure CrypteEtCopy(Tp1,Tp2: pointer; Key: String; Size: longWord); register; avec le bout de code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
        ...
        if ckbVernam64bits.Checked then begin // Avec Vernam 64 bits : ---------------
        Tp2 := TMemoryStream.Create; 
        Tp2.SetSize(BufMess.Size);
        if edClefVernam64bits.text = '' then CleVer64 := '87654321' else CleVer64 := edClefVernam64bits.text;
        CrypteEtCopy(BufMess, Tp2, CleVer64, BufMess.Size);
        RE2.Lines.BeginUpdate;
        Tp2.Position:=0; RE2.Lines.LoadFromStream(Tp2); // affichage du crypté dans RichEdit RE2
        RE2.Lines.EndUpdate;
        Tp2.free; BufMess.free;
        EXIT;
      end;
    ... mais manque de chance j'ai le message d'erreur EStackOverflow !!!???

    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