Entwickler-Ecke

Dateizugriff - Dateien verschlüsseln (RC4-verschlüsselte Streams)


Bergmann89 - Di 26.05.09 18:56
Titel: Dateien verschlüsseln (RC4-verschlüsselte Streams)
HI,

ich arbeite gerade ein einem Projekt, in dem ich bestimmte Datein auf die HDD speicher, und da die nich jeder lesen darf such ich nach ner geeigneten Methode die daten zu verschlüsseln. Ich hab mir das so gedacht: Ich speicher die ganzen Daten erstma in nem Stream. Den Stream wollt ich dann mit dem DES Verfahren verschlüsseln und dann auf der HDD speichern. Rückwärts das gleiche...
Is das ne gute Idee, oder gibt es einfachere Wege das zu lösen?

MfG Bergmann.

Moderiert von user profile iconNarses: Titel erweitert.


Narses - Di 26.05.09 18:58

Moin!

Schau mal nach Suche in: Delphi-Forum, Delphi-Library RC4, das ist schnell und sicher genug. :nixweiss:

cu
Narses


Bergmann89 - Di 26.05.09 19:45

HI,

klinkt gut, hab auch gleich versucht das zam zu basteln.
Speichern is kein ding, das mach ich so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
  str1 := Memo1.Text;
  SetLength(str2, Length(str1));

  RC4Init(Context, 'key');
  RC4Code(Context, str1[1], str2[1], Length(str1));
  RC4Done(Context);

  Stream := TFileStream.Create('test.txt', fmCreate or fmOpenReadWrite);
  Stream.Position := 0;
  Stream.Write(str2,Length(str2));
  Stream.Free;


aber beim laden meckert er rum:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  Stream := TFileStream.Create('test.txt', fmOpenRead);
  Stream.Position := 0;
  Stream.Read(str1,Stream.Size); //sorry vertippt hier stand vorher ein i anstatt str1
  Stream.Free;

  SetLength(str2, Length(str1));

  RC4Init(Context, 'key');
  RC4Code(Context, str1[1], str2[1], Length(str1));
  RC4Done(Context);

  Memo1.Text := str2;

Da kommt ne AccesViolation wenn ich die Daten aus dem Stream in den String schreiben will?!
oder muss ich den umweg über den String nicht gehen? Aber wenn ich gleich den Stream übergeb kommt auch ne Fehlermeldung.
Kann mir da nochma schnell jmd helfen?

MfG & Thx Bergmann.


jaenicke - Di 26.05.09 19:52

Ich sehe nicht, dass du irgendwo den String lädst?

Und: Kennst du TStringStream?


Narses - Di 26.05.09 19:54

Moin!

Sofern das dyn. Strings sind, dann geht das wohl eher so: ;)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Stream.Write(PChar(str)^,Length(str));

// bzw.

SetLength(str, Stream.Size);
Stream.Read(PChar(str)^,Length(str));
cu
Narses


jaenicke - Di 26.05.09 19:55

Die Multiplikation und Division durch SizeOf(Char) fehlt noch (D2009, Unicode). ;-)

// EDIT:
Also:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Stream.Write(PChar(str)^, Length(str) * SizeOf(Char));

// bzw.

SetLength(str, Stream.Size div SizeOf(Char));
Stream.Read(PChar(str)^, Length(str) * SizeOf(Char));


Bergmann89 - Di 26.05.09 19:59

@jaenicke: hab mich vertipps...sry :oops:
@Narses: hm, OK ich versuchs ma so. aber jetzt net mehr ich meld mich später

€: OK habs so weit fertig, ma gucken ob ich so auch INIs speichern und laden kann. Dazu hab ich jetzt aber kein Bock mehr ma gucken vlt mach ich da heut Nacht noch was dran ^^ Erstma VIELEN DANK für die schnelle Hilfe!!!

Ergebniss bis jetzt:

Delphi-Quelltext
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:
procedure TForm1.SaveClick(Sender: TObject);
var FileS: TFileStream;
var MemS: TMemoryStream;
var Buf1, Buf2: String;
var Context: TRC4Context;
begin
  MemS := TMemoryStream.Create;
  Memo1.Lines.SaveToStream(MemS);
  MemS.Position := 0;
  SetLength(Buf1,MemS.Size);
  MemS.ReadBuffer(PChar(Buf1)^, MemS.Size);
  MemS.Free;    

  ShowMessage(Buf1);
  SetLength(Buf2, Length(Buf1));

  RC4Init(Context, 'key');
  RC4Code(Context, Buf1[1], Buf2[1], Length(Buf1));
  RC4Done(Context);
  ShowMessage(Buf2);

  FileS := TFileStream.Create('test.txt', fmCreate and fmOpenReadWrite);
  FileS.Position := 0;
  FileS.WriteBuffer(PChar(Buf2)^,Length(Buf2));
  FileS.Free;
end;

procedure TForm1.Loadlick(Sender: TObject);
var Stream: TFileStream;
var Memory: TStringStream;
var Buf1, Buf2: String;
var Context: TRC4Context;
begin
  Stream := TFileStream.Create('test.txt', fmCreate and fmOpenReadWrite);
  Stream.Position := 0;
  SetLength(Buf1, Stream.Size);
  Stream.ReadBuffer(PChar(Buf1)^,Stream.Size);
  Stream.Free;

  SetLength(Buf2, Length(Buf1));

  RC4Init(Context, 'key');
  RC4Code(Context, Buf1[1], Buf2[1], Length(Buf1));
  RC4Done(Context);

  Memory := TStringStream.Create(Buf2);
  Memo1.Lines.LoadFromStream(Memory);
  Memory.Free;
end;


MfG Bergmann.


Narses - Di 26.05.09 20:24

Moin!

Wenn ich so deinen Code seh ;) dann könnte es sein, dass du mit der anhängenden Unit evtl. einfacher vorwärts kommst. Ist eine auf snegaH RC4-Code basierende Weiterentwicklung, die auch TStream-Adapter implementiert. :idea:

cu
Narses


Hadschi - Di 26.05.09 21:44

Kannst du auch ein kleines Beispiel geben, wie ich RC4Code einen Stream übergeben kann? Oder wie man ihn davor umwandeln muss? Und welche Streams kann ich verwenden, TMemoryStream oder nur TFileStream?

Und wenn ich euch zu blöd vorkomme, dann gebt mir nen Tipp wie man herausfinden kann wie alles funktionieren muss.


Narses - Di 26.05.09 22:44

Moin und :welcome: im Forum!

user profile iconHadschi hat folgendes geschrieben Zum zitierten Posting springen:
Kannst du auch ein kleines Beispiel geben, wie ich RC4Code einen Stream übergeben kann? Oder wie man ihn davor umwandeln muss?
Schau mal, ob du damit weiter kommst: ;)

Delphi-Quelltext
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:
procedure TfrmMain.BtnRC4ReaderClick(Sender: TObject);
  var
    RC4Reader: TRC4StreamReader;
    FSout: TFileStream;
begin
  if OpenDialog1.Execute then
    if SaveDialog1.Execute then begin
      BtnRC4Reader.Enabled := FALSE;
      RC4Reader := TRC4StreamReader.Create(
                     TFileStream.Create(OpenDialog1.FileName,fmOpenRead or fmShareDenyWrite),
                     edRC4Key.Text);
      try
        FSout := TFileStream.Create(SaveDialog1.FileName,fmCreate or fmShareDenyWrite);
        try
          FSout.CopyFrom(RC4Reader,RC4Reader.Size);
        finally
          FSout.Free;
        end;
      finally
        RC4Reader.Free;
      end;
      BtnRC4Reader.Enabled := TRUE;
    end;
end;

procedure TfrmMain.BtnRC4WriterClick(Sender: TObject);
  var
    FSin: TFileStream;
    RC4Writer: TRC4StreamWriter;
begin
  if OpenDialog1.Execute then
    if SaveDialog1.Execute then begin
      BtnRC4Writer.Enabled := FALSE;
      FSin := TFileStream.Create(OpenDialog1.FileName,fmOpenRead or fmShareDenyWrite);
      try
        RC4Writer := TRC4StreamWriter.Create(
                       TFileStream.Create(SaveDialog1.FileName,fmCreate or fmShareDenyWrite),
                       edRC4Key.Text);
        try
          RC4Writer.CopyFrom(FSin,FSin.Size);
        finally
          RC4Writer.Free;
        end;
      finally
        FSin.Free;
      end;
      BtnRC4Writer.Enabled := TRUE;
    end;
end;


user profile iconHadschi hat folgendes geschrieben Zum zitierten Posting springen:
Und welche Streams kann ich verwenden, TMemoryStream oder nur TFileStream?
Sollte mit jedem TStream-Nachfahren funktionieren. :nixweiss:

cu
Narses


Bergmann89 - Mi 27.05.09 01:35

@Narses: Danke, so is das schon viel einfacher zu handhaben ^^
Noch ein Problem hab ich. Ich hab ja INIs und die kann ich ja nur direkt aus ner Datei laden und net aus nem Stream. Gibts da auch schon irgendwie ne Lösung für oder muss ich mir da selber was basteln?

MfG Bergmann.


jaenicke - Mi 27.05.09 01:37

Wie wäre es mit TMemIniFile? :-)


Bergmann89 - Mi 27.05.09 01:52

da lad ich die Ini ja auch von ner Datei, die wird bloß im Speicher abgelegt, oder?
ich such sowas in der art:


Delphi-Quelltext
1:
2:
3:
4:
var Ini: TXXXIniFile
var Stream: TStream;

Ini := TXXXIniFile.Create(Stream);

MfG Bergmann.


Narses - Mi 27.05.09 02:12

Moin!

Das geht etwa so: ;)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var
  IniFile: TMemIniFile;
  SL: TStringList;
begin
  // in SL den Inhalt der INI-Datei bereitstellen - wie auch immer
  IniFile := TMemIniFile.Create('');
  IniFile.SetStrings(SL);
cu
Narses


Bergmann89 - Mi 27.05.09 16:04

AH, Perfekt^^
Danke schön. So ich glaub ab jetzt komm ich allein weiter.
Nochma Danke an alle.

MfG Bergmann


thepaine91 - Do 19.05.11 11:07

Zu RC4 empfehle ich diese Version: http://www.delphipraxis.net/140859-rcx-verschluesselung.html#post1101712

Dies ist eine Erweiterung des RC4 und Unicode fähig.


Narses - Do 19.05.11 11:45

Moin!

user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Zu RC4 empfehle ich diese Version: http://www.delphipraxis.net/140859-rcx-verschluesselung.html#post1101712

Dies ist eine Erweiterung des RC4 und Unicode fähig.
Was sollte da "erweitert" sein? Selbst Hagen hebt nochmal hervor, dass es RC4 ist. :nixweiss: Alles, was "neu" ist, sind die Unicode-String-Funktionen, dafür fehlen aber die TStream-Adapter aus meiner Unit oben, und genau das ist eigentlich das Interessante in diesem Thread. :idea: ;)

cu
Narses


thepaine91 - Do 19.05.11 12:04

Ja er hebt hervor das es RC4 ist aber erweitert.

2. Da hast du allerdings recht in dem Fall hat es hiermit nicht so viel zu tun. (Mein Fehler....)