Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi DEC Verschlüsselung beim Speichern einer Datei (https://www.delphipraxis.net/135716-dec-verschluesselung-beim-speichern-einer-datei.html)

TUX_der_Pinguin 16. Jun 2009 14:44


DEC Verschlüsselung beim Speichern einer Datei
 
Hallo DPler,

ich habe heute angefangen mich ein wenig mit dem Thema DEC zu beschäftigen, da ich gern etwas verschlüsselt haben möchte.

Ich habe mir ein kleines Tool geschrieben, dieses Tool speichert ein Rekord ab, dieser soll jedoch verschlüsselt
werden um eine manipulation durch einen Hex-Editor auszuschließen.

Ich hatte mir gedacht ich speicher zu erst den Rekord in einem MemoryStream ab um ihn dann zu verschlüsseln und
anschließend in einer Datei zu speichern. Beim laden müßte das dann umgekehrt sein, also aus der Datei den
verschlüsselten MemoryStream laden diesen entschlüsseln und dann daraus das Rekord zu laden.

Jedoch fehlt mir noch so der Ansatz wie ich die Verschlüsselung realisieren muß, ich blick da leider noch nicht
so ganz durch.

Verwendete Software:
DEC 5.2
Delphi 2009 Professional

Delphi-Quellcode:
procedure pSaveFile(const sFileName: String; _MyFile: tKeyFile);
var
  MStream      : TMemoryStream;
  FStream      : TFileStream;
  CipherManager : TDECCipher;

begin

  CipherManager := TDECCipher.Create;
  try

    MStream := TMemoryStream.Create;
    try
      //In den MemoryStream schreiben
      MStream.WriteBuffer(_MyFile.Header, SizeOf(_MyFile.Header));
      MStream.WriteBuffer(_MyFile.Param, SizeOf(_MyFile.Param));

      //FileStream erzeugen
      FStream := TFileStream.Create(sFileName, fmCreate or fmShareExclusive);
      try

        CipherManager.EncodeStream(MStream, FStream, MStream.Size);

      finally
        FStream.Free;
      end;

    finally
      MStream.Free;
    end;

  finally
    CipherManager.Free;
  end;

end;{pSaveFile}

mfg

TUX

Assertor 16. Jun 2009 18:09

Re: DEC Verschlüsselung beim Speichern einer Datei
 
Hi Tux,

in der DEC 5.2 befindet sich ein Beispiel (eigentlich für Unicode), müßte Example.txt oder so heißen um im Hauptverzeichnis liegen. Schau Dir das mal an, die Funktionen sind im Prinzip für Streams ähnlich, nur daß Du .Encode/.DecodeBinary gegen .Encode/.DecodeStream tauscht.

Ansonsten sollten sich auch hier im Forum einige Beispiele zur DEC5 und Streams bzw. Dateien finden lassen, z.B. http://www.delphipraxis.net/internal...t.php?p=526663.

Gruß Assertor

juergen 16. Jun 2009 23:45

Re: DEC Verschlüsselung beim Speichern einer Datei
 
Hallo Tux,

letzte Woche stand ich vor einer ähnlichen Suche welche Methode am besten wäre um ausgelagterte Dateien zu verschlüsseln.

Mir hatte jfheins sein Tip sehr geholfen, insbesondere auch für die Zukunft. :mrgreen:
Das Ganze lässt sich leicht einbinden und der Ansatz den Stream bei den Standard LoadFromStream- oder SaveToStream-Methoden zu encodieren bzw. zu kodiern gefällt mir sehr gut.
Schau mal diesen Thread

Edit: Schlagwort wäre: Stromdekorierer
An dieser Stelle mal ein großes Dankeschön an negaH und maximov für diese sehr aufwendige, tolle Arbeit! :dp:

TUX_der_Pinguin 17. Jun 2009 10:40

Re: DEC Verschlüsselung beim Speichern einer Datei
 
So den ersten versuch habe ich mit DEC versucht zu realisieren, jedoch weiß ich nicht so ganz wie ich das mit dem
Stream genau händeln muß, zur Zeit erhalte ich immer eine Fehlermeldung (Stream-Lese Fehler)

Delphi-Quellcode:
var
  ACipherClass : TDECCipherClass = TCipher_Rijndael;
  ACipherMode : TCipherMode = cmCBCx;
  AHashClass  : TDECHashClass = THash_Whirlpool;
  AKDFIndex   : LongWord = 1;


procedure pSaveFile(const sFileName: String; _MyFile: tKeyFile);
var
  MStream : TMemoryStream;
  FStream : TFileStream;
  ASalt  : Binary;
  AData  : Binary;
  APass  : Binary;

begin

    MStream := TMemoryStream.Create;
    try
      //In den MemoryStream schreiben
      MStream.WriteBuffer(_MyFile.Header, SizeOf(_MyFile.Header));
      MStream.WriteBuffer(_MyFile.Param, SizeOf(_MyFile.Param));

      //FileStream erzeugen
      FStream := TFileStream.Create(sFileName, fmCreate or fmShareExclusive);
      try

        with ValidCipher(ACipherClass).Create, Context do
        try

          ASalt := RandomBinary(16);
          APass := ValidHash(AHashClass).KDFx(glFileCryptPassword[1], Length(glFileCryptPassword) * SizeOf(glFileCryptPassword[1]), ASalt[1], Length(ASalt), KeySize, TFormat_Copy, AKDFIndex);
          Mode := ACipherMode;
          Init(APass);

          EncodeStream(MStream, FStream, MStream.Size);

        finally
          Free;
          ProtectBinary(ASalt);
          ProtectBinary(AData);
          ProtectBinary(APass);
        end;

      finally
        FStream.Free;
      end;

    finally
      MStream.Free;
    end;

end;{pSaveFile}

Im zweiten Versuch habe ich versucht das Konzept des Stromdekorierer zu realisieren. Jedoch erhalte ich hier auch noch
Fehlermeldungen (im Debug modus). Compilier ich das ganze im Release Modus kann ich zwar die Datei verschlüsselt speichern
jedoch beim öffnen ist alles durcheinander und mein Rekord wird nicht so wiederhergestellt wie ich es zuvor gespeichert habe.

Delphi-Quellcode:
procedure pOpenFile(const sFileName: String; Var _MyFile: tKeyFile; Var bError: Boolean);
var
  FStream : TRCxStreamDecorator;

begin
  //init
  _MyFile.Header.FileFormatVersion := 0;
  bError := False;

  FStream := TRCxStreamDecorator.Create(TFileStream.Create(sFileName, fmOpenRead or fmShareExclusive), True, '1234', emEncodeReading);
  try
    try
      //Header
      FStream.ReadBuffer(_MyFile.Header, SizeOf(_MyFile.Header));

      if _MyFile.Header.FileFormatVersion = CurrentVersion then begin

        //Parameter
        FStream.ReadBuffer(_MyFile.Param, SizeOf(_MyFile.Param));

      end
      else begin
        Application.MessageBox(PWideChar('Die Datei entspricht nicht dem aktuellen Datei-Format ('+IntToStr(CurrentVersion)+')'), 'Fehler', 48);
        bError := True;
      end;{else}

    except
      bError := True;
    end;

  finally
    FStream.Free;
  end;


end;{pOpenFile}

Delphi-Quellcode:
procedure pSaveFile(const sFileName: String; _MyFile: tKeyFile);
var
  FStream : TRCxStreamDecorator;

begin
  FStream := TRCxStreamDecorator.Create(TFileStream.Create(sFileName, fmCreate or fmShareExclusive), True, '1234', emEncodeWriting);
  try
    //Header
    FStream.WriteBuffer(_MyFile.Header, SizeOf(_MyFile.Header));

    //Parameter
    FStream.WriteBuffer(_MyFile.Param, SizeOf(_MyFile.Param));
  finally
    FStream.Free;
end;
Die Fehlermeldung verweist auf eine Prozedur in der RCx.pas...
Delphi-Quellcode:
procedure RC4Init(var RC4: TRC4Context; const Key: String);
var
  R,S,T,K: Byte;
  U,L: Integer;
begin
  L := Length(Key);
  with RC4 do
  begin
    I := 0;
    J := 0;
    for S := 0 to 255 do D[S] := S;
    R := 0;
    U := 0;
    for S := 0 to 255 do
    begin
      if U < L then K := PByteArray(Key)[U] else K := 0;
      Inc(U);
      if U >= L then U := 0;

      Inc(R, D[S] + K); //<-- Integer Überlauf
      T   := D[S];
      D[S] := D[R];
      D[R] := T;
    end;
  end;
end;

juergen 17. Jun 2009 10:51

Re: DEC Verschlüsselung beim Speichern einer Datei
 
Hallo Tux,

auf die Schnelle meine ich mich zu erinnern, dass man in deiner Procedur procedure pSaveFile...
das -> FStream.WriteBuffer...
nur einmal aufrufen darf.

TUX_der_Pinguin 17. Jun 2009 11:02

Re: DEC Verschlüsselung beim Speichern einer Datei
 
Nee also das klappt auch irgendwie nicht, ausserdem habe ich ja noch nach wievor einen Integerüberlauf in der RCx.pas.

himitsu 17. Jun 2009 11:15

Re: DEC Verschlüsselung beim Speichern einer Datei
 
zum Integerüberlaug: du hast nicht zufällig die Unit aus dem Anhang verwendet?
http://www.delphipraxis.net/internal...049637#1049637

wenn ja, dann such mal in RCx.pas diese Zeile
Delphi-Quellcode:
{ $A+,B-,C-,D-,E-,F-,G+,H+,I-,J+,K-,L-,M-,N+,O+,P+,Q-,R-,S-,T-,U+,V+,W-,X+,Y-,Z1}
und lösche das leerzeichen zwischen { und $ :angel2:


und wegen dem "ist alles durcheinander im Record" ... hab in dem Thread da drüben das selbe Problem.

TUX_der_Pinguin 17. Jun 2009 11:33

Re: DEC Verschlüsselung beim Speichern einer Datei
 
Zitat:

Zitat von himitsu
zum Integerüberlaug: du hast nicht zufällig die Unit aus dem Anhang verwendet?
http://www.delphipraxis.net/internal...049637#1049637

wenn ja, dann such mal in RCx.pas diese Zeile
Delphi-Quellcode:
{ $A+,B-,C-,D-,E-,F-,G+,H+,I-,J+,K-,L-,M-,N+,O+,P+,Q-,R-,S-,T-,U+,V+,W-,X+,Y-,Z1}
und lösche das leerzeichen zwischen { und $ :angel2:


und wegen dem "ist alles durcheinander im Record" ... hab in dem Thread da drüben das selbe Problem.


Ja ich hab die Unit genommen, ok muß ich mal schauen das ich das Leerzeichen entferne.

Hmm ist blöd wäre zu schön wenns so klappen würde ... ich hoffe es gibt da eine Lösung.

juergen 17. Jun 2009 17:25

Re: DEC Verschlüsselung beim Speichern einer Datei
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,

wir reden im Moment von 2 verschiedenen Problemen (Unicode-Thematik und das Nichtfunktionieren des Stromdekorierers bei Tux)

Zur Veranschaulichung wie der Strom Dekorierer bei mir funktioniert habe ich mal ein Projekt erstellt (im Anhang).
Ich habe mich in diesem Test-Projekt für das Erstellen einer abgeleiteten StringList entschieden.
Nur von dieser StringList werden dann die beiden Methoden SaveToFile() und LoadFromFile() "umgeleitet" auf die Ver- und Entschlüsselungs-Methoden.
So lässt sich das Ganze sehr schön verwenden. :-D



Edit 1: (17.06.09) Neues Test-Projekt angefügt.
Nun wird:
a) beim Start des Programmes eine evtl. vorhandene, verschlüsselte Datei direkt in die StringList und dann in die Listbox eingelesen,
b) Fehlerbehandlung wenn bei der Methode LoadFromFile() keine Datei vorhanden ist... :wink:

Edit 2: (18.06.09) Hinweise seitens himitsu in das Testprojekt mit übernommen und Kleinigkeiten verschlimmbessert :mrgreen:

TUX_der_Pinguin 18. Jun 2009 07:59

Re: DEC Verschlüsselung beim Speichern einer Datei
 
Vielen dank für das Beispiel juergen, ich habs jetzt hin bekommen, jedoch mußte ich nicht nur in der RCx.pas
die Kompilerschalter aktivieren sondern in den beiden anderen Units auch weil ich ständig Integerüberlaufe
bekommen habe. Die Verschlüsselung scheint jetzt aber zu funktionieren, ich kann mein Rekord speichern
und wenn ich es wieder lade ist das Rekord wieder vollständig hergestellt.

Im grunde fehlte nur WriteSalt und ReadSalt.

Speichern der Datei:
Delphi-Quellcode:
procedure pSaveFile(const sFileName: String; _MyFile: tKeyFile);
var
  FStream : TRCxStreamDecorator;

begin
  FStream := TRCxStreamDecorator.Create(TFileStream.Create(sFileName, fmCreate or fmShareExclusive));
  try
    FStream.Password := '1234';
    FStream.WriteSalt;

    //Header
    FStream.WriteBuffer(_MyFile.Header, SizeOf(_MyFile.Header));

    //Parameter
    FStream.WriteBuffer(_MyFile.Param, SizeOf(_MyFile.Param));
  finally
    FStream.Free;
  end;

end;{pSaveFile}

Öffnen der Verschlüsselten Datei:
Delphi-Quellcode:
procedure pOpenFile(const sFileName: String; Var _MyFile: tKeyFile; Var bError: Boolean);
var
  FStream : TRCxStreamDecorator;

begin
  //init
  _MyFile.Header.FileFormatVersion := 0;
  bError := False;

  FStream := TRCxStreamDecorator.Create(TFileStream.Create(sFileName, fmOpenRead or fmShareExclusive));
  try
    try
      FStream.Password := '1234';
      FStream.ReadSalt;

      //Header
      FStream.ReadBuffer(_MyFile.Header, SizeOf(_MyFile.Header));

      if _MyFile.Header.FileFormatVersion = CurrentVersion then begin
        //Parameter
        FStream.ReadBuffer(_MyFile.Param, SizeOf(_MyFile.Param));
      end
      else begin
        Application.MessageBox(PWideChar('Die Datei entspricht nicht dem aktuellen Datei-Format ('+IntToStr(CurrentVersion)+')'), 'Fehler', 48);
        bError := True;
      end;{else}

    except
      bError := True;
    end;{try..except}

  finally
    FStream.Free;
  end;{try..finally}

end;{pOpenFile}
Wie gut bzw. wie sicher die Verschlüsselung jetzt ist, soll mir soweit egal sein. Als Passwort werde ich natürlich
etwas anders nehmen als "1234" :wink: aber mir ging es nur darum die jenigen abzuschrecken die mal probieren wollen
ob man da nicht was manipulieren kann wenn man einen Wert ändert, da in meinem Rekord fast nur Boolschewerte gespeichert
werden, hätte man ja das ein oder andere Byte mal umdrehen können von daher ist das jetzt vollkommen in Ordnung.

Ich bedanke mich bei der tollen hilfe und wünsche noch einen schönen Tag.

mfg

TUX

himitsu 18. Jun 2009 08:42

Re: DEC Verschlüsselung beim Speichern einer Datei
 
ich schau gleich mal, was bei mir falsch läuft.

aber zu den Booleans ... wenn man was da äntert, dann ist die Chance 254 zu 255, daß der Wert danach auf True steht ... es sei denn, du nutzt einen "fehler" in der Nutzung des Booleans aus.

Zitat:

vergleiche nie auf True
Delphi-Quellcode:
b := Boolean(3);

if not b then // wird nie aufgerufen
if b then    // wird aufgerufen

if b = false then // wird nie aufgerufen
if b = true then // wird AUCH NIE aufgerufen

himitsu 18. Jun 2009 11:22

Re: DEC Verschlüsselung beim Speichern einer Datei
 
ich hab den Fehler endlich gefunden :shock:

gibt mal dem Laden den "richtigen" EncodeMode mit an :!:
> emEncodeReading

in deinen Demos bleibt der immer aus seinem Defaultwert "emEncodeWriting"
und wenn man bei Lesen da emEncodeReading angibt, geht garnichts mehr.



[add]
PS: :tongue:
Code:
procedure TForm1.btn_Listbox_fillClick(Sender: TObject);
begin
  [color=#ff0000][b]My_StringList.Clear;[/b][/color]
  for i := 0 to StrToInt(se1.Text) [color=#ff0000][b]- 1[/b][/color] do

juergen 18. Jun 2009 15:09

Re: DEC Verschlüsselung beim Speichern einer Datei
 
@himitsu,
Zitat:

Zitat von himitsu
ich hab den Fehler endlich gefunden :shock:

:thumb:

Zitat:

Zitat von himitsu
[add]
PS: :tongue:
Code:
procedure TForm1.btn_Listbox_fillClick(Sender: TObject);
begin
  [color=#ff0000][b]My_StringList.Clear;[/b][/color]
  for i := 0 to StrToInt(se1.Text) [color=#ff0000][b]- 1[/b][/color] do

:oops: :mrgreen: ...danke für dein Hinweis. Das sind die typisch doofen Fehler die immer wieder mal passieren.
Ich habe das Testprojekt im Thread #9 angepasst und neu hochgeladen (falls es nochmal benötigt wird)


@Tux,
schön das ich dir helfen konnte :thumb:

himitsu 18. Jun 2009 15:14

Re: DEC Verschlüsselung beim Speichern einer Datei
 
Das Problem ist nur, daß der Fehler nicht bei mir liegt,
sondern im TRCxStreamDecorator soballd man beim Schreiben und Lesen den selben Zugriffs-Wert nimmt,
klappt es ja,

aber eigentlich hätt ich erwartet, daß man zum Lesen die Leseoption "emEncodeReading" nimmt und zu Schreiben die Schreiboption "emEncodeWriting".


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:28 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz