Announcement

Collapse
No announcement yet.

Nochmal Delphi Encryption Compendium!!

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Nochmal Delphi Encryption Compendium!!

    Hallo Hagen!!<br>
    <br>
    Sorry das ich schon wieder nerv, aber ich habe wieder ein Problem und zwar wenn ich einen Buffer verschlüsseln möchte. <br>
    Mein Problem ist das ich einen eigenen Datentyp habe. <br>
    <br>
    type<br>
    TProperties = record <br>
    Status : TStatus;<br>
    RoomID : String;<br>
    User : String<br>
    end;<br>
    <br>
    var<br>
    st, stEn, stDe : TProperties;<br>
    <br>
    procedure TForm1.Button1Click(Sender: TObject);<br>
    begin<br>
    Cipher.EncodeBuffer(st, stEn, SizeOf(st));<br> //Hier liegt glaube ich das Problem. Muss ich die Daten größe mit SizeOf angeben???<br>
    end;<br>
    <br>
    procedure TForm1.Button2Click(Sender: TObject);<br>
    begin<br>
    Cipher.DecodeBuffer(stEn, stDe, SizeOf(stEd));<br> //Hier kommt nur schwachsin raus. Beziehungsweise das Program bricht mit einer Access violation ab!! <br>
    mControl.Lines.Add(stDe.RoomID);<br>
    mControl.Lines.Add(stDe.User);<br>
    if stDe.Status = stOpen then<br>
    mControl.Lines.Add('Open')<br>
    else if stDe.Status = stWrongID then<br>
    mControl.Lines.Add('WrongID')<br>
    else if stDe.Status = stClose then<br>
    mControl.Lines.Add('Close')<br>
    else<br>
    mControl.Lines.Add('Komisch');<br>
    end;<br>
    <br>
    Also welchen wert muss ich da übergeben. Ich habe schon -1 probiert so wie bei den Streams, klappt aber auch nicht!! Ich habe befor ich das alles gemacht habe auch den InitKey aufgerufen!!!<br><br>
    Vielen Dank für deine Hilfe im vorraus!!<br>
    <br>
    mfg<br>
    <br>
    Daniel

  • #2
    Hi

    Dein Record Typ ist sehr unglücklich gewählt da er mit LongStrings arbeitet und zusätzlich nicht packed ist. Wenn Du records wählst und diese speichern/laden oder verschlüsseln willst, müssen ALLE Daten IN dem record bzw. dessen Speicherbereich enthalten sein. In Deinem falle stellen die beiden String aber ZEIGER auf einen NICHT im record enthaltenen Speicherbereich dar. Angenommen SizeOf(TStatus) = Byte dann ist die Speichergröße dieses Records 3* 4 = 2 bytes. 2 x Sizeof(Pointer) für die beiden Strings und 4 Bytes für den TStatus da der record nicht gepackt ist fügt der Compiler 3 bytes nach TStatus als Füller ein damit die nachfolgenden Felder an 4 bytes Grenze ausgerichtet sind. Es gibt nun zwei wege:<br>
    <li>Du änderst den record typ<br>
    <li>oder Du schreibst Speicher/Laderoutinen für die Records<br>

    <pre>

    1. methode<br>

    type
    TProperties = packed record
    Random: array[0..6] of Byte; // 7 bytes
    Status: TStatus; // 1 byte
    RoomID: String[123]; // 124 bytes
    UserID: String[123]; // 124 bytes
    end;// SizeOf(TProperties) = 256<br>

    procedure EncodeProperties(var Properties: TProperties; const Key: String);
    begin
    with TCipher_Blowfish.Create(Key, nil) do
    try
    RndSeedBuffer(Properties.Random, SizeOf(Properties.Random));
    EncodeBuffer(Properties, Properties, SizeOf(Properties));
    finally
    Free;
    end;
    end;<br>

    2. Methode<br>

    type
    TProperties = record
    Status: TStatus;
    RoomID: String;
    UserID: String;
    end;<br>

    procedure EncodeProperties(Stream: Stream; const Properties: TProperties; const Key: String);
    var
    M: TMemoryStream;
    Rnd: array[0..7] of byte;
    I: Integer;
    begin
    M := TMemoryStream.Create;
    try
    // 8 zufalls bytes speichern = Salt
    RndSeedBuffer(Rnd, SizeOf(Rnd));
    M.Write(Rnd, SizeOf(Rnd));
    // Status
    M.Write(Properties.Status, SizeOf(Properties.Status));
    // Länge + RoomID
    I := Length(Properties.RoomID);
    M.Write(I, SizeOf(I));
    M.Write(PChar(Properties.RoomID)^, I);
    // Länge + UserID
    I := Length(Properties.UserID);
    M.Write(I, SizeOf(I));
    M.Write(PChar(Properties.UserID)^, I);
    with TCipher_Blowfish.Create(Key, nil) do
    try
    I := M.Size;
    // Gesamtlänge unverschlüsselt speichern
    Stream.Write(I, SizeOf(I));
    M.Position := 0;
    // den verschlüsselten MemoryStream in Stream speichern
    EncodeStream(M, Stream, M.Size);
    finally
    Free;
    end;
    finally
    M.Free;
    end;
    end;<br>

    </pre>

    Gruß hage

    Comment


    • #3
      So nun ein bischen Erklärungen:<br>
      1.) verzichte auf die TCiphermanager Komponente, da dies eigentlich nur für den "Drag&Design" user bestimmt ist. Aus Sicherheitsaspekten gesehen ist sie aber unsicherer als die direkte Klassennutzung wie oben gezeigt. hauptgrund ist das die Lebenszeit eines Crypto Objects so kurz wie möglich sein sollte, das verringert den Footprint und die schnelle Entdeckung und reduziert Resourcen. Die Cipher/Hash sind so schnell das die ständige Erzeugung/Zerstörung nicht ins Gewicht fällt.<br>
      2.) Wie Du siehst verschlüssele ich immer als erstes ca. 8 bytes Zufallsdaten. Das IST sicherer als ein IV=InitVector und es wird dadurch eine PlainText/CipherText Attacke verhindert. Ansonsten ohne diesen Zufall wird mit dem gleichen Key die gleichen daten immer gleich verschlüsselt, d.h. der CipherText ist immer gleich. Der Zufall bewirkt das der CipherText IMMER anders ist. Es sollten ca. 8 bytes Minimum sein da 8 bytes * 8 Bits = 64Bits = 2^64 besser wären natürlich 128 Bits Zufall.<br>
      3.) Die 1. Variante speichert im record TProperties ALLE benötigten Informationen ab. Dadurch kann dieser Record wie ein Datenbereich behandelt werden der geladen/gespeicher/verschl. oder kopiert werden kann. nachteilig ist das dann immer eine feste Stringlänge verbraucht wird, egal ob benötigt oder nicht. Auch siehst Du das solche Record immer PACKED deklariert sind.<br>
      4.) Die 2. Methode speichert die daten aus dem Record dynamisch, das bedeutet mehr Aufwand, ist aber flexibler in der Speichergröße da sowohl im Speicher als auch dann im Stream=File nur die minimal benötigte Datenmenge benutzt wird.<br>
      5.) es hängt nun von deinem Geschmack/Verständniss/Lust&Laune ab welche Methode die bessere für Dich ist.<br>
      6.) Alle Deine probleme hänge weniger mit dem DEC zusammen, sondern eher mit dem programmierknownledge und den PASCAL Sprachkenntnissen.<br>
      7.) Du wirst mir also verzeihen wenn ich demnächst in meinen Antworten ein bischen mehr Wissen vorraussetze.<br>
      8.) ich bevorzuge die 1. methode, da man mit solchen Records sehr einfach arbeiten kann. Allerdings sollte dann von Anfang an klar sein was man will, damit sich das Dateiformat nicht ständig ändert.<br>
      Mehrere solche Records nacheinander in einer datei gespeichert verhalten sich dann so wie eine datenbankdatei, man kann also direkt z.b. zum X'ten Record seeken und nur diesen Laden.<br>
      In der zweiten methode ist dafür die unverschlüsselte Länge=M.Size gedacht. Durch auslesen dieser Länge und weiterpositionieren um diese Länge kann man sich direkt von einem Record zum nächsten durchhangeln.<br>
      9.) Für große datenmenge, die zusätzlich noch z.b. übers WEB übertragen werden sollen, ist natürlich 2. Methode besser<br>
      10.) Beider methoden eignen sich auch um z.b. erst ALLE records in einen Stream zu speichern und erst diesen in einem Rutsch zu verschlüsseln.

      gruß hage

      Comment


      • #4
        Hi<BR>
        <BR>
        Vielen Dank für deine schnelle Antwort!! Ich werde das gleich mal alles ausprobieren!! Aber ich denke das wird schon Klappen!
        <BR><BR>
        mfg<BR><BR>Daniel Göh

        Comment


        • #5
          Hi<BR>
          <BR>
          Du hast recht. Meine kenntnisse in sachen record und Stream beziehen sich darauf das ich weis wie ich sie dekariere und benutze!!<BR>
          Ich brauche das ganze um Netzwerk Traffic zu verschlüsseln. Deswegen wollte ich ja auch Streams benutzen. Da ich jedoch den record über UDP schicke (Das ist ne lange geschichte und hat was mit dem Algorithmus zu tun) kam diese problem auf. Ich benutze die Indy Komponenten die über UDP nur Texte oder Buffer senden können!! Das ist das ärgerliche!!<BR>
          Ich habe ja noch Zeit zu lernen!!<BR>
          <BR>
          Also vielen Dank nochmal!!<BR><BR>
          Gruß<BR><BR>Danie

          Comment


          • #6
            <pre>

            var
            M: TMemoryStream;
            begin
            M := TMemoryStream.Create;
            try
            SaveWhatYouWantIntoStream(M);
            FuckingIndy.SendBuffer(M.Memory^, M.Size);
            finally
            M.Free;
            end;
            end;

            <pre>

            Gruß Hage

            Comment

            Working...
            X