Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Große Dateien Komprimieren und zeit gleich verschlüsseln (https://www.delphipraxis.net/214526-grosse-dateien-komprimieren-und-zeit-gleich-verschluesseln.html)

DelTurbo 24. Jan 2024 13:52

Große Dateien Komprimieren und zeit gleich verschlüsseln
 
Hi,
ich habe eine Frage (ja wie immer). Ich habe rausgefunden das TIdCompressorZLib relativ schnell ist. Wenn ich das so mache wie in meinem Beispiel. Ich habe nur das wesentlich drin gelassen, also keine abfrage mehr ob die Datei existiert usw.

Delphi-Quellcode:
procedure ShrinkFile(FName:String);
var
  IStream  :TStream;
  OSTream  :TStream;
  Compress :TIdCompressorZLib;
begin
    IStream:=TFileStream.Create(FName,fmOpenRead);
    OSTream:=TFileStream.Create('test.pak',fmCreate);
    Compress:=TIdCompressorZLib.Create(nil);
    Compress.DeflateStream(IStream,OStream,2);
    Compress.Free;
    IStream.Free;
    OSTream.Free;
end;
Nun zu meiner Frage: Wie kann ich mich da irgendwie einklinken, also in den OStream und die Daten mit irgendwas aus dcpcrypt Verschlüsseln. Ich würde es ja im Speicher machen, also Datei lesen dann Verschlüsseln und wieder raus schreiben. Aber ich weiß nicht wie groß die Dateien sind. Es kann sein das die gar nicht in den Speicher passen.
Die Inputdatei zu verschlüsseln ist quatsch weil es dann kaum noch was zum packen gibt.

Da ich schon länger suche und Garnichts finde habe ich es mal ChatGPT versucht. Aber das ding "erfindet" Sachen die es nicht gibt. Also unbrauchbar. Bitte keine hinweise ich solle Zip o.ä. nutzen.

Vielen Dank im voraus

Delphi.Narium 24. Jan 2024 14:35

AW: Große Dateien Komprimieren und zeit gleich verschlüsseln
 
Habe mal bei der "Konkurenz" nachgefragt:
Zitat:

Zitat von meine Frage
Wie kann ich in Delphi eine Datei per TIdCompressorZLib komprimieren und anschließend via TStream verschlüsseln? Können Sie mir bitte dafür einen Quelltext zur Verügung stellen?

Die Antwort darauf:
Zitat:

Zitat von Bing AI
Ja, ich kann Ihnen dabei helfen. Hier ist ein einfacher Code, der zeigt, wie Sie eine Datei mit `TIdCompressorZLib` komprimieren und dann mit `TStream` verschlüsseln können. Bitte beachten Sie, dass dieser Code nur zu Demonstrationszwecken dient und Sie ihn entsprechend Ihren Anforderungen anpassen müssen.

```delphi

Delphi-Quellcode:
uses
  IdZLibCompressorBase, IdCompressorZLib, System.Classes;

procedure CompressAndEncryptFile(const SourceFile, DestFile: string);
var
  SourceStream, DestStream: TFileStream;
  Compressor: TIdCompressorZLib;
begin
  SourceStream := TFileStream.Create(SourceFile, fmOpenRead);
  try
    DestStream := TFileStream.Create(DestFile, fmCreate);
    try
      Compressor := TIdCompressorZLib.Create;
      try
        // Komprimieren Sie den Quellstrom in den Zielstrom
        Compressor.CompressStream(SourceStream, DestStream);

        // Setzen Sie die Position des Zielstroms zurück, um die Verschlüsselung durchzuführen
        DestStream.Position := 0;

        // Fügen Sie hier Ihren Verschlüsselungscode hinzu
        // ...
      finally
        Compressor.Free;
      end;
    finally
      DestStream.Free;
    end;
  finally
    SourceStream.Free;
  end;
end;
```
Zitat:

Zitat von Bing AI
In diesem Code wird die `CompressStream`-Methode von `TIdCompressorZLib` verwendet, um den Inhalt des Quellstroms (SourceStream) zu komprimieren und in den Zielstrom (DestStream) zu schreiben¹. Nach der Kompression wird die Position des Zielstroms auf den Anfang zurückgesetzt, damit die Verschlüsselung durchgeführt werden kann. Sie müssen Ihren eigenen Verschlüsselungscode hinzufügen, um den komprimierten Strom zu verschlüsseln.

Bitte beachten Sie, dass die `CompressStream`-Methode mehrere Parameter hat, darunter `ALevel`, `AWindowBits`, `AMemLevel` und `AStrategy`, die die Komprimierungseinstellungen steuern¹. Sie können diese Parameter an Ihre spezifischen Anforderungen anpassen. Wenn Sie nicht sicher sind, welche Werte Sie verwenden sollen, können Sie die Standardwerte verwenden, die in der Indy-Bibliothek definiert sind¹.

Ich hoffe, das hilft! Wenn Sie weitere Fragen haben, lassen Sie es mich bitte wissen.

Quelle: Unterhaltung mit Bing, 24.1.2024
(1) delphi - Where are the parameters for Indy's TIdCompressorZLib .... https://stackoverflow.com/questions/...am-method-docu.
(2) delphi - Using TIdCompressorLib to Decompress gzip file - Stack Overflow. https://stackoverflow.com/questions/...ress-gzip-file.
(3) TidCompressorZLib - Delphi-PRAXiS. https://www.delphipraxis.net/175744-...essorzlib.html.
(4) Delphi Indy TIdHTTP mit SSL und GZip - Delphi-PRAXiS. https://www.delphipraxis.net/198032-...-und-gzip.html.

Sieht für mich so aus, als könnte es funktionieren.

Auf weitere Nachfrage von mir:
Zitat:

Zitat von Nachfrage
Könnten Sie den Quelltext bitte dahingehend ergänzen, indem sie für die Verschlüsselung eine beliebige Verschlüsselungsmethode aus der dcpcrypt-Bibliothek verwenden?

Die Antwort darauf fällt so aus:
Zitat:

Zitat von Bing AI
Ja, ich kann Ihnen dabei helfen. Hier ist ein erweiterter Code, der zeigt, wie Sie eine Datei mit `TIdCompressorZLib` komprimieren und dann mit `TDCP_rijndael` aus der `DCPcrypt`-Bibliothek verschlüsseln können¹². Bitte beachten Sie, dass dieser Code nur zu Demonstrationszwecken dient und Sie ihn entsprechend Ihren Anforderungen anpassen müssen.

```delphi

Delphi-Quellcode:
uses
  IdZLibCompressorBase, IdCompressorZLib, DCPrijndael, DCPsha256, System.Classes;

procedure CompressAndEncryptFile(const SourceFile, DestFile: string; const Key: string);
var
  SourceStream, DestStream: TFileStream;
  Compressor: TIdCompressorZLib;
  Cipher: TDCP_rijndael;
  Hash: TDCP_sha256;
  KeyHash: array[0..31] of Byte;
begin
  SourceStream := TFileStream.Create(SourceFile, fmOpenRead);
  try
    DestStream := TFileStream.Create(DestFile, fmCreate);
    try
      Compressor := TIdCompressorZLib.Create;
      try
        // Komprimieren Sie den Quellstrom in den Zielstrom
        Compressor.CompressStream(SourceStream, DestStream);

        // Setzen Sie die Position des Zielstroms zurück, um die Verschlüsselung durchzuführen
        DestStream.Position := 0;

        // Erstellen Sie den Hash des Schlüssels
        Hash := TDCP_sha256.Create(nil);
        try
          Hash.Init;
          Hash.UpdateStr(Key);
          Hash.Final(KeyHash);
        finally
          Hash.Free;
        end;

        // Verschlüsseln Sie den komprimierten Strom
        Cipher := TDCP_rijndael.Create(nil);
        try
          Cipher.Init(KeyHash, SizeOf(KeyHash) * 8, nil);
          Cipher.EncryptStream(DestStream, DestStream, DestStream.Size);
          Cipher.Burn;
        finally
          Cipher.Free;
        end;
      finally
        Compressor.Free;
      end;
    finally
      DestStream.Free;
    end;
  finally
    SourceStream.Free;
  end;
end;
```
Zitat:

Zitat von Bing AI
In diesem Code wird die `CompressStream`-Methode von `TIdCompressorZLib` verwendet, um den Inhalt des Quellstroms (SourceStream) zu komprimieren und in den Zielstrom (DestStream) zu schreiben¹. Nach der Kompression wird die Position des Zielstroms auf den Anfang zurückgesetzt, damit die Verschlüsselung durchgeführt werden kann. Der Schlüssel wird dann mit `TDCP_sha256` gehasht und der Hash wird verwendet, um den `TDCP_rijndael`-Verschlüsselungsalgorithmus zu initialisieren². Schließlich wird der komprimierte Strom mit `TDCP_rijndael` verschlüsselt².

Bitte beachten Sie, dass die `CompressStream`-Methode mehrere Parameter hat, darunter `ALevel`, `AWindowBits`, `AMemLevel` und `AStrategy`, die die Komprimierungseinstellungen steuern¹. Sie können diese Parameter an Ihre spezifischen Anforderungen anpassen. Wenn Sie nicht sicher sind, welche Werte Sie verwenden sollen, können Sie die Standardwerte verwenden, die in der Indy-Bibliothek definiert sind¹.

Ich hoffe, das hilft! Wenn Sie weitere Fragen haben, lassen Sie es mich bitte wissen.

Quelle: Unterhaltung mit Bing, 24.1.2024
(1) Encrypt a string in Delphi 7 using DCPCrypt (3DES). https://stackoverflow.com/questions/...-dcpcrypt-3des.
(2) encryption - Delphi 7 - DCPCrypt - TDCP_rijndael - DecryptString - How .... https://stackoverflow.com/questions/...o-make-it-work.
(3) DCPcrypt - Free Pascal wiki. https://wiki.freepascal.org/DCPcrypt.
(4) GitHub - StephenGenusa/DCPCrypt: Cryptographic Component Library. https://github.com/StephenGenusa/DCPCrypt.

Kannst Du damit was anfangen?

DelTurbo 24. Jan 2024 14:47

AW: Große Dateien Komprimieren und zeit gleich verschlüsseln
 
Hui,
erstmal vielen dank. Ich werde mir das mal ansehen, ist ja nicht grade wenig und wie immer eine Rückmeldung geben.

mytbo 24. Jan 2024 15:18

AW: Große Dateien Komprimieren und zeit gleich verschlüsseln
 
Ist im Artikel ZIP-Datei als Datenspeicher mit verschlüsseltem Inhalt beschrieben. Quelltext ist dabei.

Bis bald...
Thomas

DelTurbo 24. Jan 2024 16:20

AW: Große Dateien Komprimieren und zeit gleich verschlüsseln
 
@Delphi.Narium,
tut mir leid das die Rückmeldung so lange gedauert hat. Der Ansatz ist bei kleinen Files die Lokal auf der Platte liegen super. Ich habe das allerdings die ganze zeit auf dem LAN mit einem 15GB File getestet. Der Nachteil an dieser Lösung ist, das die gepackte Datei nochmal gelesen und geschrieben wird. Und das dauert halt. Möchte man dann noch ein Verify machen muss man es ein drittes mal lesen.
Alleine wie man verschlüsselt hätte ich suchen müssen. Was bei dir drin ist und gut beschrieben ist.

Aber ich habe auch eine Lösung. Ich habe mir die IdZLib.pas in meinen Projekt Ordner geholt und schreibe die "einfach" um. Ich habe die stelle gefunden an dem der gepackte Block geschrieben wird. Ist unter DoCompressStream eine Procedure die WriteOut heißt. Vor dem Schreiben werde ich den Stream dann verschlüsseln. Ich habe die IdZLib.pas extra kopiert weil ich ja das Indy selber nicht nur noch für das eine Projekt nutzen möchte.

@mytbo,
Deine Sache habe ich mir runtergeladen und schaue mal wie das dort gelöst ist.

Das Problem ist halt das es kleine oder auch richtig große Dateien sein können.

Ich danke euch beiden für die Hilfe.

himitsu 24. Jan 2024 17:08

AW: Große Dateien Komprimieren und zeit gleich verschlüsseln
 
Gab es nicht ZLib-Streams, welche den einen Stream per Constroktor rein bekommen und dann alle Schreib-/Lesevorgänge an diesen Stream durchreichen,
nachdem für das Stück vom aktuellen Write-Befehl durch die Komprimierung lief.

Ähliches hatte ich doch auch schon für Verschlüsselungs-Streams gesehen.

Also die beisen Streams hintereinander schalten, und dann innen das Read/Write/Copy, welches direkt oder mit je einem kleinen Puffer quasi direkt durchgereicht wird.


PS: Ziehe die ZIP-Klasse im Delphi ... da machen doch (glaub ich) die Streams sowas.

mytbo 24. Jan 2024 18:15

AW: Große Dateien Komprimieren und zeit gleich verschlüsseln
 
Zitat:

Zitat von DelTurbo (Beitrag 1532504)
Das Problem ist halt das es kleine oder auch richtig große Dateien sein können.

Einfach 7Zip nehmen:
Delphi-Quellcode:
uses
  mormot.core.base,
  mormot.core.text,
  mormot.core.unicode,
  mormot.core.os,
  mormot.lib.win7zip;

begin
  var dataFile: TFileName := MakePath([Executable.ProgramFilePath, 'TestData.dat']);
  var libWriter: I7zWriter := New7zWriter(fh7z);
  libWriter.SetCompressionLevel(3);
  libWriter.SetPassword('TopSecret');
  if libWriter.AddFile(dataFile, StringToUtf8(ExtractFileName(dataFile))) then
    libWriter.SaveToFile(MakePath([Executable.ProgramFilePath, 'TestData.7z']))
  else
    ShowMessage('Something went wrong!');
Die 7za.dll kann von der offiziellen Seite geladen werden.

Bis bald...
Thomas

DelTurbo 25. Jan 2024 09:51

AW: Große Dateien Komprimieren und zeit gleich verschlüsseln
 
Hi,
nun weiß ich noch vom letzten mal warum du die uses bei eschrieben hast. Ja, ich bin lernfähig, soweit es das Alter noch zulässt... :-D:-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:35 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