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.
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.
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.[EDIT]
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.
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]
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 *)
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+.
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.
J'aimerais bien savoir ce que vous pensez de ce programme, ou si vous avez des améliorations à suggérer.
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.
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 ?
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
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.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 !
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 :
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 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;
A+.
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; ...
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 :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).J'aimerais bien savoir ce que vous pensez de ce programme, ou si vous avez des améliorations à suggérer.
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 :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.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 ?
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)
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 ?
@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...
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 !
Re-salut,
tourlourou :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.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 !
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+.
Bonjour Gilbert,
Je suis d'accord avec toi : plusieurs couches ça protège mieux !
Bonjour,
Juste une remarque pour combler un oubli à propos de :et de :Valochette : Crypter un fichier byte par byteIl 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.Roland Chastain : Je vais me pencher sur le "Vigenère".
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+.
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
Bonjour à tous et salut René,
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.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...
A propos de :
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).... soit : planquer la clé dans le crypté (ce qui oblige à posséder des routines privées pour l'y placer et l'y retrouver).
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+.
Salut chaleureux à toi, Gilbert
Depuis nos derniers échanges, je n'ai pratiquement rien fait sauf cette procedure :
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
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;
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 !
Re-salut,
Salut chaleureux à toi, René.Super!!! Cela va permettre d'ajouter une couche de sur-cryptage supplémentaire.Depuis nos derniers échanges, je n'ai pratiquement rien fait sauf cette procedure CrypteEtCopy(Tp1,Tp2: pointer; Key: String; Size: longWord); register
Je la testerai demain vu l'heure.
Cordialement et A+.
Bonjour,
J'ai testé la procedure CrypteEtCopy(Tp1,Tp2: pointer; Key: String; Size: longWord); register; avec le bout de code suivant :
... mais manque de chance j'ai le message d'erreur EStackOverflow !!!???
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;
A+.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager