Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi DEC 5.1 wie benutzen? (https://www.delphipraxis.net/107798-dec-5-1-wie-benutzen.html)

delphin06 2. Feb 2008 11:40


DEC 5.1 wie benutzen?
 
Hallo

Ich möchte gerne ein listview verschlüsselt abspeichern. Ich hab dann hier im Forum das DEC von Hagen gefunden. Allerdings wird hier viel nur mit der älteren Version beschrieben. Also ich habe mal die Unit DECCipher eingebunden und habe dan uch 2 passende Funktionen für meinen anwendungsfall gefunden und zwar EncodeStream und DecodeStream.
Allerdings verstehe ich nich was das alles für Parameter sind. Ich muss ja erstma den key initialisieren mit init()

Meine Frage ist nun, was bedeuten die Parameter

von init():
Delphi-Quellcode:
const Key; Size: Integer; const IVector; IVectorSize: Integer; IFiller: Byte = $FF
und von decode/encode:
Delphi-Quellcode:
const Source, Dest: TStream; const DataSize: Int64; const Progress: IDECProgress = nil
Ich hoffe mir kann jemand helfen. ich weiß einfach nich was ich da eintragen soll.

Gruß

Luckie 2. Feb 2008 11:53

Re: DEC 5.1 wie benutzen?
 
Ich arbeite gerade an einer Unit mit Hagen zusammen, die zeigt wie man das DEC richtig benutzt um eine Datei zu verschlüsseln. Mal sehen, eventuell bekomme ich das dieses Wochenende noch fertig.

delphin06 2. Feb 2008 12:06

Re: DEC 5.1 wie benutzen?
 
Das wäre ja super! Weil mir fehlt da irgendwie de vorgehensweise, was ich alles aufrufen muss und wozu

delphin06 2. Feb 2008 14:32

Re: DEC 5.1 wie benutzen?
 
ich hab mir mal das filecrypt beispiel angeguckt von jus.

Jez hab ich versucht das n bisschen abzuändern, dass anstatt einer Datei direkt ein Stream verwendet wird. Aber irgendiwe klappt das nich. Da kommt dann ein Fehler mit der Meldung "Stream-Lesefehler" und der tritt in der procedure:

Delphi-Quellcode:
procedure TDECCipher.EncodeStream(const Source, Dest: TStream; const DataSize: Int64; const Progress: IDECProgress);
begin
  DoCodeStream(Source, Dest, DataSize, Context.BlockSize, Encode, Progress);
end;
auf.

Hier mal meine abgeänderte version:
Delphi-Quellcode:
procedure EncodeMStream(const ADestFilename: String; const APassword: Binary;
                       ACipher: TDECCipherClass = nil; AMode: TCipherMode = cmCTSx;
                       AHash: TDECHashClass = nil);
 var
  Dest: TStream;

  procedure Write(const Value; Size: Integer);
  begin
    Dest.WriteBuffer(Value, Size);
  end;

  procedure WriteByte(Value: Byte);
  begin
    Write(Value, SizeOf(Value));
  end;

  procedure WriteLong(Value: LongWord);
  begin
    Value := SwapLong(Value);
    Write(Value, SizeOf(Value));
  end;

  procedure WriteBinary(const Value: Binary);
  begin
    WriteByte(Length(Value));
    Write(Value[1], Length(Value));
  end;

var
  Sourcestr: TMemoryStream;
  Seed: Binary;
begin
  {if ASourceFileName=ADestFilename then
  begin
    showmessage('Source file and destination file must not be equal!');
    exit;
  end; }
  ACipher := ValidCipher(ACipher);
  AHash := ValidHash(AHash);
  Seed := RandomBinary(16);
  //Source := TFileStream.Create(ASourceFileName, fmOpenReadWrite);
  Sourcestr:=TMemorystream.Create();
  try
    sourcestr.WriteComponent(Form1.listview1);
    Dest := TFileStream.Create(ADestFilename, fmCreate);
    try
      with ACipher.Create do
        try
          Mode := AMode;
          Init(AHash.KDFx(APassword, Seed, Context.KeySize));

          WriteLong(Identity);
          WriteByte(Byte(Mode));
          WriteLong(AHash.Identity);
          WriteBinary(Seed);
          WriteLong(Sourcestr.Size);
          EncodeStream(Sourcestr, Dest, Sourcestr.Size);
          WriteBinary(CalcMAC);
        finally
          Free;
        end;
    finally
      Dest.Free;
    end;
      //ProtectStream(Source);
  finally
    Sourcestr.Free;
  end;
  //DeleteFile(AFileName);
end;
Was habe ich falsch gemacht?

negaH 2. Feb 2008 19:32

Re: DEC 5.1 wie benutzen?
 
Wenn du in einen leeren Stream zb. 1024 Bytes geschrieben hast, wo steht dann der Stream.Position ? Bei 1024 richtig.
Wenn du nun anschließend aus dem Stream was lesen möchtest un Stream.Position = Stream.Size wieviele Bytes kann man dann noch aus dem Stream lesen ? Ah, garkeine da man ja am Ende des Streams ist, richtig.

Delphi-Quellcode:
SourceStr.WriteComponente(blabla)
if SoureStr.Position = SourecStr.Size then
  ShowMessage('Ähm, wenn du nachher mit SourceStr.Read() was lesen möchtest dann solltest du auch SourceStr.Positon := 0 aufrufen');
Also Stream.Position :=0; bevoir du versucht wieder aus dem Stream zu lesen.

einen Stream verschlüsseln auf einfachste Weise
Delphi-Quellcode:
with TCipher_Rijndael.Create do              // Cipher erzeugen
try
  Init('Passwort');                          // mit Passwort initialisieren
  EncodeStream(SourceStream, DestStream, -1); // Stream verschlüssen
finally
  Free;                                      // Cipher freigeben
end;
Beachte das obiges Beispiel die Minimalkonfiguration darstellt, man kann es aus Sicht der Kryptographie noch besser=sicherer machen.

Gruß Hagen

PS: gewöhne dir an deutsch zu schreiben, ich weiß es ist schwer auf modischen Schnickschnack zu verzichten besonders wenn man bischen extrovertiert erscheinen möchte und sein "Image" aufbauen möchte. Aber ansonsten antworte ich einfach nicht mehr ;)

delphin06 3. Feb 2008 10:09

Re: DEC 5.1 wie benutzen?
 
Zitat:

Zitat von negaH
PS: gewöhne dir an deutsch zu schreiben, ich weiß es ist schwer auf modischen Schnickschnack zu verzichten besonders wenn man bischen extrovertiert erscheinen möchte und sein "Image" aufbauen möchte. Aber ansonsten antworte ich einfach nicht mehr ;)

OK. Ich werde es versuchen^^ Aber ehrlich gesagt weiß ich nicht was du für ein Problem hast.

Ich danke dir für deine Hilfe! Damit kann ich schonmal was anfangen. Ich habe noch nicht allzu viel mit Streams gearbeitet.

Aber eine Frage habe ich nochmal:
1. Was bedeutet das "-1" in der Zeile
Delphi-Quellcode:
EncodeStream(SourceStream, DestStream, -1);


Gruß

[EDIT] Ich habe jetzt wie du gesagt hattest die Stream Position vorher auf 0 gesetzt und das funktioniert jetzt wunderbar. Nochmal RIESEN Dankeschön! Genauso sollte das funktionieren. Der obere Code ist natürlich besser als die Minimalkonfiguration, weil da kann ich auch prüfen ob das Passwort richtig ist.

negaH 3. Feb 2008 12:07

Re: DEC 5.1 wie benutzen?
 
Zur Beantwortung deiner Frage würde ich die Unit DECCipher.pas öffnen und im Interfaceteil der Unit nach der Deklaration von TDECCipher.EncodeStream() suchen.

Du findest dann das hier

Delphi-Quellcode:
   
procedure EncodeStream(const Source, Dest: TStream; const DataSize: Int64; const Progress: IDECProgress = nil);
Danach würde ich in die Implementierung dieser Funktion gehen und du findest den Aufruf der internen Procedure DoCodeStream(). Diese Proc ist in Pascal geschrieben und damit eigentlich auch lesbar ;)

DataSize bezeichnet also die Anzahl an Bytes die aus Stream "Source" nach "Dest" verschlüsselt werden sollen. Man kann mit DEC's Streamfunktionen, bzw. eigentlich mit fast allen Streamfunktionen die halbwegs logisch aufgebaut sind, auch nur Teile einen Streams verschlüsseln. Zb. man ver-entschlüsselt ab dem 1000 Bytes eines Streams nur 100 Bytes nach Dest. Dazu wird Stream.Position benutzt.

Wenn man zb. ab .Position := 1000 alles bis .Size = 1500 aus einem TFileStream verschlüsseln möchte müsste man es so aufrufen:

Delphi-Quellcode:
  Source.Position := 1000;
  EncodeStream(Source, Dest, Source.Size - Source.Position);
Das Subtrahieren von .Size - .Position verlangt aber beim TFileStream ständige Aufrufe von .Seek(). Nun Seek() wiederum nutzt das Windows-FileAPI und das ist speziell bei .Seek() arsch langsam. Dh. wenn man Dateioperationen möglichst schnell haben möchte dann sollte man die Aufrufe von .Size und .Position reduzieren und optimieren.

Nun der Aufruf von

Delphi-Quellcode:
  Source.Position := 1000;
  EncodeStream(Source, Dest, -1);
ist identisch zu obigem Aufruf, spart aber zwei Aufrufe von .Seek() da wir .Size und .Position nicht mehr aufrufen.

Die -1 bedeutet also: ver/entschlüssele alles von der aktuellen .Position bis zum Ende des Stream's = .Size.

Zudem fängt es Fehler ab. Wenn zb. Source.Positon und/oder Soure.Size vom Programierer in lokalen Variablen selber berechnet wird (siehe meine Implementation von DoCodeSream) und dabei aber falsch berechnet wurde so das Position > Size wäre so ergibt sich ein negativer Wert von DataSize. In diesem Falle fängt das DoCodeStream() ab und berechnet selber die Anzahl an Bytes von .Position bis .Size des Streams.

Gruß Hagen

negaH 3. Feb 2008 12:27

Re: DEC 5.1 wie benutzen?
 
Zitat:

OK. Ich werde es versuchen^^ Aber ehrlich gesagt weiß ich nicht was du für ein Problem hast.
Ich habe ansich kein Problem. Nur vertrete ich die Meinung das wir Deutschen in unserer Sprache ständig irgendwelchen Modetrends bzw. absichtlich geschaffenen Wortschöpfungen der kommerziellen Industrie nachrennen. Das erfolgt ohne plausiblen Grund, besonders weil die deutsche Sprache eine sehr präzise und schöne Sprache ist. Im Umkehrschluß, meine Meinung zur Realität, ergibt sich für mich daraus eine Handlungsanweisung: nämlich kämpfe aktiv gegen solche Unsitten. Da Du der Fragende bist und ich der potentiell beste Antworter für deine Frage, habe ich die Möglichkeit indirekt Druck auf dich auszuüben, und das mache ich auch. Denn ich möchte das wir in 50 Jahren auch noch gutes Deutsch reden können. Denn die Sprache ist es die unsere Denkweise und Kommunikationsform untereinander definiert, ändert man die Sprache nach rein kommerziellen oder nach irgendwelchen Harlemgang Slang so ändert man die Denkweise der Menschen. Das möchte ich nicht und so kämpfe ich dagegen.

Zudem definiert sich die Gesamtqualität der Delphi Praxis eben auch gerade über die benutzte Sprache und der zwischenmenschliche Umgangston. Je besser dieser ist desto höher ist die Wahrscheinlichkeit das in Fragen Delphi/Pascal die Delphi Praxis im deutschsprachigen Raum die Nase vorne hat.

Ich möchte also verhindern das immer mehr Leute hier deinen Jargon nachahmen, bzw. an Hand dieses Threads erkennen können, wie ich gerne reden möchte.

Aus meiner Sicht handelst du also egoistisch: du stellst deine Frage in deinem Slang und erwartest das dir speziell auch geantwortet wird und damit auch geholfen wird. Andere Hilfesuchende mit dem gleichen Problem sprechen nicht deine Sprache und somit wäre dieser Thread auch für diese Leute wenig hilfreich. Du bist der Hilfesuchende und ich stelle klar das du es bist der sich an den potentiell Antwortenden anpassen musst, nicht umgekehrt. Es ist meine Zeit die ich verschwende um deine Probleme zu lösen, und wenn du dann noch im Slang redest verlangst du von mir das ich das in mein Deutsch übersetzen soll. Im Grunde also unverschämt von dir.

Ich bin also nur ehrlich und offen zu dir und sage dir direkt was ich an Konsequenzen zu ziehen bereit sein werde. Ich könnte auch einfach meine Zeit anders nutzen und lasse dich mit deiner Frage im Stich. Dann würdest du irgendwann schon von selber merken das irgendwas nicht stimmt, da du nämlich Zeit verlierst, und änderst dich dann doch. Du würdest dich also selber anpassen und verändern in deiner Sprache und schwups wird dir auch wieder geholfen. Du als Fragender hast also im Grunde die Pflicht deine Fragen so zu formulieren das ein Antwortender dir schnell helfen kann, ansonsten antwortet dir eben keiner Ergo: mit deinem Slang schiesst du dir in's eigene Knie.

Gruß Hagen

[edit]
Das es nun konkret dich getroffen hat ist -> Pech gehabt ;)
[/edit]

DeddyH 3. Feb 2008 12:32

Re: DEC 5.1 wie benutzen?
 
Gut gebrüllt, Löwe :thumb:

juergen 3. Feb 2008 13:07

Re: DEC 5.1 wie benutzen?
 
Die Argumentation von negaH gefällt mir sehr gut! :thumb:
Ich hoffe nicht nur mir ist in letzter Zeit die Gleichgültigkeit der Mitglieder aufgefallen, wenn man sie daraufhin anspricht.
So ganz nach dem Motto: ist halt Chat-Sprache...Müsst ihr alle damit leben.
Das Delphipraxis Forum ist eben kein Chat! (Chatfunktion wäre sogar vorhanden, hat aber nichts mit den öffentlichen Threads zu tun)

Ich denke auch, dass die darauf angesprochenen Leute nicht vorsätzlich so handeln ,
sie sind sich ihrer verwendeten was-auch-immer-Sprache leider nicht bewusst, weil anscheinend im tägl. Umfeld nur so geschrieben wird.

Beleidigte Reaktionen sind dann aber falsch, schließlich möchte der Threadsteller ja etwas.
Und viele Mitglieder hier sind bereit da auch Zeit zu investieren und zu helfen.

Die Eigenschaft OBJEKTIV mit Kritik umzugehen ist ein wesentlicher Faktor zur persönlichen Weiterentwicklung.
[/mein Wort zum Sonntag]

negaH 3. Feb 2008 13:21

Re: DEC 5.1 wie benutzen?
 
Andererseits möchte ich auch nicht das das Forum hier zu einem ständigen Nörglerforum verkommt, mit Links zum Duden und so'n Quatsch. Ich habe also nichts dagegen einzuwenden das sich die deutsche Sprache auch weiterentwickeln kann. Das ist auch ein Grund dafür das ich einfach kurz und bündig darauf reagiere -> willst du Hilfe dann rede deutsch mit mir, fertig. Das mag zwar arrogant oder sonstwas erscheinen, aber die Faktenlage ist nun mal so, ich kann diesen Druck ausüben. Das heist also nicht das ich ein Nationalist oä. bin, sondern ich reagiere aktiv, statt es hinzunehmen.

Also nochmal: dein "jez" ist die Mücke die ich zum Elefanten gemacht habe. Das du dran glauben musstest lag einfach daran das ich Bock und Zeit hatte eine Kritik zu formulieren. Normalerweise antworte ich dann einfach nicht und widme mich meinen Katzen, meiner Freundin, meinen Basteleien oder sonst was Interessanterem.

Gruß Hagen

Luckie 3. Feb 2008 13:27

Re: DEC 5.1 wie benutzen?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hänge hier mal meine Unit mit der Klasse an, um eine Datei mit dem DEC zu ver- und entschlüsseln. Ich werde dass dann noch mal richtig offiziell veröffenlichen.

Dezipaitor 3. Feb 2008 13:55

Re: DEC 5.1 wie benutzen?
 
Kurze Frage:
Sind die DEC Units closed source und nur für Freeware-Programme?
Wie kam es denn dazu?

Die Muhkuh 3. Feb 2008 13:59

Re: DEC 5.1 wie benutzen?
 
Hi,

DEC Part I ist imho open source, DEC Part II nicht.

negaH 3. Feb 2008 16:48

Re: DEC 5.1 wie benutzen?
 
Aus gegebenen Anlaß ;)

Luckie's Unit ist ein Beispiel dafür wie man die Funktionalität vom DEC in eine Klasse kapseln kann.
DEC selber ist nur eine Zusammenstellung von vorgefertigten kryptographischen Verfahren. Mehr nicht, aber auch nicht weniger, da ich hoffe das die Qualität des DECs gerade im Source und seinen Schnittstellen sehr hoch ist.
DEC muß also nicht so wie üblich wie eine Komponente installiert werden, sondern es reicht einfach die notwendigen Units einzubinden und den Pfad auf die Source oder kompilierten Units oder Packages zu legen.

Bei der Entwicklung einer kryptographischen Bibliothek hat der Programmierer ganz besondere Anforderungen, im Gegensatz zu normalen Bibliotheken. Einige dieser Anforderungen widersprechen sich, zb. möglichst viel zu unterstützen und damit eine hohe Komplexität im Gegensatz zur kryptrographischen Sicherheit und damit möglichst anwendungssicheren und somit einfach gestrickten und denoch flexiblen Schnittstellen. Nun DEC versucht eben nicht alles zu können sondern beschränkt sich auf eine klare und sichere Schnittstelle. Daraus ergibt sich das ein Nutzer vom DEC noch einiges drumherum basteln muß und nichts im DEC quasi readymade ist.

Soweit zum Vorwort ;) Kommen wir nun zur konkreten Aufgabe eine Datei zu verschlüsseln.

Der einfache aber unflexible und nicht ganz kryptographisch sichere Weg

Delphi-Quellcode:
procedure EncryptFile(const ASourceFileName, ADestFileName, APassword: String);
begin
  with TCipher_Rijndael.Create do
  try
    Init(APassword);
    EncodeFile(ASourceFileName, ADestFileName);
  finally
    Free;
  end;
end;
fertig. Bei diesem Source fällt folgendes auf:

- Einfachheit
- Unflexibel da der verwendete Cipheralgo. usw. nicht konfigurierbar ist
- Verfahrensunsicher da zb. nicht klar ist was passieren würde wenn ASourceFileName und ADestFileName identisch sind
- kryptographisch nicht so besonderst sicher da das APassword direkt im Cipher.Init benutzt wird und somit einige effiziente Angriffe möglich sind

Also müssen bzw. können wir das verbessern, fragt sich nur womit man am besten anfängt. Wir wollen folgendes abändern

1.) Konfigurierbarkeit
Das ist eine Forderung nach kryptographischer Sicherheit denn wenn in der Zukunft bekannt werden sollte das AES-Rijndael als Verfahren geknackt worden sein sollte dann müssen wir möglichst schnell unseren Source abändern. Sowas macht man zB. über globale Konstanten.

2.) krypto. Sicherheit inkrementieren
Wir wissen das es heute schon effiziente Angriffe auf direkt benutzte Paswörter gibt, zb. Rainbow Tabellen. Obiger Source ist dagegen anfällig also müssen wir das abändern. Nun taucht das erste wirkliche Problem auf. Wie ändern wir das ab wenn es dafür keine anerkannten Standards gibt ? Klar, wir müssen einen prohibitären Weg einschlagen, besonders bei der Frage der Datenformate usw. Wir können aber unsere benutzten Algorithmen dabei an empfohlenen Vorgehensweisen ausrichten. Diese Diskrepanz entsteht immer wenn man anfängt pure krypto. Verfahren in krypto. Protokollen anzuwenden. Es gibt PKCS, PGP, IEEE, NIST, AES, ASN1 usw. usw. Standards und alle machen es anders in ihren Datenformaten. Allen liegen zwar die gleichen mathmatisch kryptographsich orientierten Forderungen zugrunde aber was hinten rauskommt ist absolut unterschiedlich. DEC hatte sich mal vorgenommen die wichtigsten dieser Standards auch umzusetzen aber wie jeder sich denken kann ist das ne Menge Holz an Arbeit. Im Besonderen wenn man bedenkt das dies meistens kommerziell orientierte Standards sind und man sich defakto damit in seiner Bibliothek dem Goodwill dieser Konzerne aussetzt. Ergo, die Entscheidung ist die das der Endbenutzer des DECs sich selber entscheiden muß. Das heist aber auch das in der korrekten Benutzung vom DEC auch der Benutzer dieser Bibliothek Ahnung von Kryptographie haben muß. Naja meiner Meinung nach sollte jeder der Kryptographie benutzt auch das notwendige Wissen besitzen, denn nur das ist echte Sicherheit.
Zurück zum Thema: wir erhöhen die Sicherheit des APassword enorm wenn wir dazu eine randomisierte KDF benutzen. KDF bedeutet Key Derivation Function und übersetzt Schlüsselableitungsfunktion (ein schönes deutsches Wort das es exakt auf den Punkt bringt ;) )
Eine KDF erzeugt also auf irgendeine sichere Weise aus einem Schlüssel=APassword einen anderen Schlüssel mit kryptographisch besseren Eigenschaften. Später mehr dazu.

3.) Flexibilität
Wir wissen das man in der VCL eine Datei ver-entschlüsselt über TStream Objekte. Also wäre es sinnvoll gleich damit eine Funktion zu schreiben und dann darauf aufsetztend die Ver/Entschlüsselung von Dateien. Von Haus aus kann das ja das DEC schon aber wir wollen ja auch ansonsten noch Drumherum mehr.

Also fangen wir an mit der TStream basierten Funktion und der Konfigurierbarkeit:

Delphi-Quellcode:
const
  ACipherClass: TDECCipherClass = TCipher_Rijndael;
  ACipherMode: TDECCipherMode = cmCTSx;

procedure Encrypt(ASource, ADest: TStream; const APassword: String);
begin
  Assert(ASource <> ADest, 'Encrypt(), ASource must be distinct to ADest');

  with ValidCipher(ACipherClass).Create do
  try
    Mode := ACipherMode;
    Init(APassword);
    EncodeStream(ASource, ADest, -1);
  finally
    Free;
  end;
end;
Als erstes nutzen wir Assert() um zu prüfen ob die Objekte ADest und ASource unterschiedlich sind. Sowas prüft DEC intern nicht ab da es durchaus möglich sein könnte das es eine Streamklasse geben könnte die inplaced und überlappend auf dem gleichen Datenbereich arbeitet. Ich kenne zwar sowas nicht aber möglich wäre es. In unserem Beispiel möchten wir aber sicherstellen das man nur mit zwei unterschiedlichen Streamobjekten arbeiten kann. Deshalb eine Assertion da es ja ein Programmierfehler ist wenn er auftritt.

Als nächstes erzeugen wir wieder eine Cipherinstanz, aber diesesmal überprüfen wir mit ValidCipher(ACipherClass) ob die übergebene Klassenreferenz eine gültige ist. Man könnte also ACipherClass auf nil initialisieren und ValidCipher() würde die mit DECCipher.SetDefaultCipherClass() global installierte Cipherklasse zurückgeben. Dh. DEC enthält quasi schon eine globale Variable um eine Cipherklasse, Hashklasse und DECFormat Klasse zu registrieren. Wir nutzen dieses Feature hier aber nur indirekt.
Dann initialisieren wir das Cipherobjekt, erstmal den Feedbackmodus und dann das Passwort. Und danach wird der Stream verschlüsselt.

Wir können also in Zukunft sehr schnell unsere Procedure konfigurieren. Man könnte auch alle notwendigen Parameter der Procedure Encrypt() übergeben aber das hat weniger Vorteile als man denkt. Normalerweise entscheidet sich der Programmierer für einen Algorithmus pro Algorithmentyp. Er überlässt also eben nicht die Wahl der Qual dem Anwedner seiner selbst geschaffenen Schnittstellen sondern legt alles fest. Das erhöht dann die Anwendungssicherheit und wir möchten ja das Ziel errichen das wir eine Readymade Schnittstelle haben.

Nun möchten wir aber ua. die Passwordsicherheit inkrementieren indem wir eine KDF benutzen.

Delphi-Quellcode:
const
  ACipherClass: TDECCipherClass = TCipher_Rijndael;
  ACipherMode: TDECCipherMode = cmCTSx;
  AKDFClass: TDECHashClass = THash_SHA1;
  AKDFIndex: Cardinal = 1;
  AKDFSaltSize: Byte = 16;

procedure Encrypt(ASource, ADest: TStream; const APassword: String); overload;
var
  Salt,SessionKey: Binary;
begin
  Assert(ASource <> ADest, 'Encrypt(), ASource must be distinct to ADest');

  with ValidCipher(ACipherClass).Create do
  try
    Salt := RandomBinary(AKDFSaltSize);
    SessionKey := ValidHash(AKDFClass).KDFx(APassword, Salt, Context.MaxKeySize, TFormat_Copy, AKDFIndex);

    Mode := ACipherMode;
    Init(SessionKey);
 
    ADest.WriteBuffer(Salt[1], Length(Salt));

    EncodeStream(ASource, ADest, -1);
  finally
    Free;

    ProtectBinary(SessionKey);
    ProtectBinary(Salt);
  end;
end;
Wir erzeugen einen Zufallssalt "Salt" der 16 Bytes groß ist. Das ist also ein 16 Bytes großer Speicherbereich der mit Zufallsdaten befüllt wird. Nun wird mit Hilfe einer KDF aus diesem Salt und dem APassword ein Cipher.Context.MaxKeySize langer Wert berechnet. Dieser Wert ist auf Grund des Salt pseudozufällig und hat exakt die Größe an Bytes die nötig ist um die Sicherheit des Cipher's auszunutzen. Zb. beim AES Rijndael gibt es eine 128, 196 und 256 Bit Verschlüsselungsstärke. In unserem Beispiel nutzen wir also immer die 256 Bit Verschlüsselung des AES aus.
Auf Grund der Hashfunktion, das ist eine kryptographisch sichere Einwegfunktion, kann man nicht so ohne weiteres vom so erzeugten Sessionkey auf das Passwort zurückrechnen. Aber viel wichtiger ist eben die Eigenschaft das wenn wir die exakt gleichen Daten im Stream mit dem exakt gleichen Passwort erneut verschlüsseln wir jedesmal einen anderen Salt benutzen und somit auch jedesmal einen anderen Sessionkey erzeugen. Somit wird in ADest immer ein anderes Produkt der Verschlüsselung entstehen. Wir haben quasi über die Schlüsselableitung per zufälligem Salt einen psuedozufälligen Sessionkey erzeugt und somit eine pseudozufällige Verschlüsselung der Daten. Zu jedem der möglichen Passwörter wird es also 2^128, da 16 Bytes Salt = 128 Bit sind, verschiedene Salts und somit minimal 2^128 mögliche Sessionkeys zu einem spezifischen Passwort.
Eine Wörterbuchattacke erzeugt offline zu jedem der möglichen Passwörter die benutzten Sessionkeys. Wenn aber die KDF bei ihrer Berechnung einen 128 Bit Salt benutzt so heist dies das man nun statt nur einem Wörterbuch nun 2^128-1 mal mehr Wörterbücher erzeugen müsste. Das ist praktisch gesehen bisher unmöglich. Ergo: über diese Methode haben wir zusätzlichen kryptographsichen Schutz eingebaut und die Gesamtsicherheit des Systemes erhöht.
Der AKDFIndex ist eine Zahl mit der man die Berechnung des Sessionkeys applikationsbezogen serialisieren kann. Mit einem anderen AKDFIndex wird man also auch andere Sessionkeys produzieren.

Da der Salt zufällig gewählt wurde müssen wir diesen nun auch für die notwenige Entschlüsslung abspeichern. Also schreiben wir diesen Salt in unseren Destinationstream. Das führt zu einer Expansion der Datenmenge, dh. in ADest sind später mehr Bytes gespeichert als in ASource, hier konkret 16 Bytes == AKDFSaltSize.

Am Ende der Procedure zerstören wir den Inhalt von Salt und Sessionkey im Speicher. Das erhöht ein bischen die Anwendungssicherheit und schützt vor offline Spionagesoftware die zb. das SwapFile oder die Harddisk des Betriebsystemes auslesen kann.

Nun bauen wir drumherum die Schnittstelle um Dateien zu verschlüsseln.

Delphi-Quellcode:
procedure Encrypt(const ASourceFileName, ADestFileName, APassword: String); overload;
var
  ASource, ADest: TStream;
  ATempFileName: String;
begin
  ATempFileName := ChangeFileExt(ADestFileName, '.$$$');
  try
    ASource := TFileStream.Create(ASourceFileName, fmOpenRead or fmShareDenyNone);
    try
      ADest := TFileStream.Creare(ATempFileName, fmCreate);
      try
        Encrypt(ASource, ADest, APassword);
      finally
        ADest.Free;
      end;
    finally
      ASource.Free;
    end;
    DeleteFile(ADestFileName);
    RenameFile(ATempFileName, ADestFileName);
  except
    DeleteFile(ATempFileName);
    raise;
  end;
end;

Es hat sich bewährt bei der Verschlüsselung von Dateien erstmal die Originaldatei in eine temporäre Datei zu verschlüsseln und im Anschluß die temporär angelegte Datei einfach umzubennen. So erlangt man wiederum eine höhere Anwendungssicherheit da nun zb. bei einer Exception keine Datei unabsichtlich zerstört wird. Man kann auch ASourceFileName identisch zu ADestFileName festlegen.

Die Procedure DeleteFile() sollte noch durch eine Procedure wie SecureDeleteFile() ersetzt werden. Diese Procedure macht das gleiche wie DeleteFile() nur mit dem Unterschied das sie vor dem Löschen noch mehrmals den Inhalt der Datei überschreibt. Diesen Vorgang nennt man Wipe. Allerdings ist es auf den meisten Betriebsystemen utopisch anzunehmen das man damit wirklich alle Daten der Dateien gelöscht hätte.

Delphi-Quellcode:
procedure SecureDeleteFile(const AFileName: String);
var
  Stream: TStream;
begin
  if FileExists(AFileName) then
  begin
    Stream := TFileStream.Create(AFileName, fmOpenReadWrite or fmShareDeny);
    try
      ProtectStream(Stream);
    finally
      Stream.Free;
    end;
    DeleteFile(AFileName);
  end;
end;
Nun möchten wir noch die Flexibilität im fertigen GUI verbessern. Dazu wäre es hilfreich wenn wir zb. eine Progressbar im GUI hätten damit der Anwender sieht wie's vorwärtsgeht. Auch möchten wir zb. das der Anwender die Verschlüsselung abbrechen kann.
Dazu stellt DEC schon eine relativ komfortable Möglichkeit zur Verfügung, das Interface IDECProgress.
Alle Methoden von DEC Klassen die zb. mit Hilfe von TStream's arbeiten unterstützen dieses Interface. Wir ändern erstmal unsere beiden Encrypt() Procedure dingehend ab.

Delphi-Quellcode:
procedure Encrypt(ASource, ADest: TStream; const APassword: String; const AProgress: IDECProgress = nil); overload;
var
  Salt,SessionKey: Binary;
begin
  Assert(ASource <> ADest, 'Encrypt(), ASource must be distinct to ADest');

  with ValidCipher(ACipherClass).Create do
  try
    Salt := RandomBinary(AKDFSaltSize);
    SessionKey := ValidHash(AKDFClass).KDFx(APassword, Salt, Context.MaxKeySize, TFormat_Copy, AKDFIndex);

    Mode := ACipherMode;
    Init(SessionKey);
 
    ADest.WriteBuffer(Salt[1], Length(Salt));

    EncodeStream(ASource, ADest, -1, AProgress);
  finally
    Free;

    ProtectBinary(SessionKey);
    ProtectBinary(Salt);
  end;
end;

procedure Encrypt(const ASourceFileName, ADestFileName, APassword: String; const AProgress: IDECProgress = nil); overload;
var
  ASource, ADest: TStream;
  ATempFileName: String;
begin
  ATempFileName := ChangeFileExt(ADestFileName, '.$$$');
  try
    ASource := TFileStream.Create(ASourceFileName, fmOpenRead or fmShareDenyNone);
    try
      ADest := TFileStream.Creare(ATempFileName, fmCreate);
      try
        Encrypt(ASource, ADest, APassword, AProgress);
      finally
        ADest.Free;
      end;
    finally
      ASource.Free;
    end;
    DeleteFile(ADestFileName);
    RenameFile(ATempFileName, ADestFileName);
  except
    DeleteFile(ATempFileName);
    raise;
  end;
end;

Fertig. Nun wenden wir das mal in einem TForm an.

Delphi-Quellcode:
type
  TForm1 = class(TForm, IDECProgress)
    Button1: TButton;
    Progressbar1: TProgressbar;

    procedure Button1Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  private
    FInAction: Integer;
    FNextTick: Cardinal;
    procedure Process(const Min,Max,Pos: Int64); stdcall;
  end;

procedure TForm1.Process(const Min,Max,Pos: Int64); stdcall;
begin
  if GetTickCount >= FNextTick then
  begin
    FNextTick := GetTickCount + 100;
    Application.ProcessMessages;
    ProgressBar1.Position := Round((Max - Min) / 100 * (Pos - Min));
    ProgressBar1.Update;
    if FInAction > 1 then
      Abort;
  end;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := FInAction = 0;
  if not CanClose and (MessageBox('Wollen Sie die aktuelle Aktion abbrechen ?') = mrYes) then
    Inc(FInAction);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if FInAction = 0 then
  try
    FInAction := 1;
    Button1.Caption := 'Abort';
    // Button2.Enabled := False; // hier alle Bedienelemente deaktivieren die nicht bedienbar sein dürfen
    FNextTick := 0;
    try
      Encrypt(GetSourceFileName, GetDestFileName, GetPassword, Self);
    except
      on E: EAbort do ShowMessge('Abbruch durch Benutzer')
       else raise;
    end;
  finally
    FinAction := 0;
    Button1.Caption := 'Encrypt';
    // Button2.Enabled := True;
  end else
    Inc(FInAction);
end;
Das ist mal ein stark abstrahiertes Beispiel. Auf dem TForm1 sitzt ein Button1 mit Caption := 'Encrypt'.
Die Funktionen GetSourceFileName, GetDestFileName und GetPassword müssen von euch noch implementiert werden.

Drückt der Anwender nun Button1 das erste mal so ist FInAction == 0, wir verzweigen also in den try finally Block oben im Source. Nun setzen wir FinAction auf 1 und zeigen somit an das wir gerade ver-entschlüsseln. Zusätzlich setzen wir die .Caption von Button1 auf 'Abort' und fangen an eine Datei zu verschlüsseln. Dabei übergeben wir Self als IDECProgress Interface, was dazu führt das die Methode TForm1.Process() periodisch duch die internen DEC Funktionen aufgerufen wird. In TForm1.Process() rufen wir Application.ProcessMessages; auf und somit friert das GUI der Anwendung nicht mehr ein. Danach updaten wir die Progressbar1 und prüfen ob FInAction > 1 ist. Wenn das der Fall ist muß der Anwender in der Zischenzeit erneut den Button1 gedrückt haben oder er hat versucht das TForm1 zu schließen. Denn nur in diesem beiden Methoden inkrementieren wir FInAction falls es > 0 ist. Wir lösen dann einfach per Abort; eine stille Exception aus. Diese EAbort Exception unterbricht dann die internen DEC Verschlüsselungsmethoden, da ja aus diesen heraus erst die Methode TForm1.Process() aufgerufen wurde. Natürlich fangen wir diese Exception in unserer zu äusserst liegenden Methode, hier .Button1Click(), gezielt ab.

Diese Methode hat den Vorteil das das GUI nicht mehr einfrieren kann, das der Benutzer einen Fortschrittsbalken sieht, das er die Aktion sauber abbrechen kann und wir benötigen keine TThread's, keine Synchronisation usw. Der Nachteil besteht darin das der Programmierer sehr sehr genau darauf achten muß welche Bedienelemente er aktiviert bzw. deaktiviert. Meistens wird man alle Steuerelemente deaktivieren in .Button1Click() und nur das TForm1 selber und den Button1 der zum Abbruch dient aktiviert lassen. Das ist wichtig !

Nochwas zu FNextTick. Es kann nun vorkommen das TForm1.Process() sehr sehr schnell nacheinander aufgerufen wird. Das führt dann dazu das durch den Aufruf von Application.ProcessMessages; und das Updatiung der ProgressBar1 die Gesamtperformance stark reduziert. Wir verhidnern dies indem wir über FNextTick und GetTickCount() nur alle minimal 100 Milisekunden diese Aktionen durchführen, also ca. 10 mal pro Sekunde. Das ist für einen Menschen ausreichend, sowohl in der Visualisierung des Fortschrittsbalken wie auch in der
Interaktion des Benutzers über die Steuerelemente.

Möchte man ohne diese Möglichkeit der Progressbar arbeiten so ruft man Encrypt() einfach ohne den letzten Parameter Self auf. Durch unseren Defaultparameter ist dieser dann == nil und intern wird ohne dieses Callback-Interface gearbeitet.

Man muß auch nicht das IDECProgress Interface direkt im TForm1 implementieren und könnte eine eigene Klasse oder Komponente dafür schreiben. Allerdings erachte ich das bei diesem geringen Aufwand und dem direkten logischen Zusammenhang zwischen IDECProgress zum GUI einer Applikation für weniger geschickt, bzw. oversized. Man muß halt immer abwägen. Jede Kapselung solcher Funktionen zb. in eigene Klassen/Komponenten stellt eine Erhöhung der Komplexität dar und macht meistns reingarnichts wirklich besser. Somit reuziert sich die Gesamtsicherheit da man mehr Fehler reinbaut, der Anwender keinen Vorteil erlangt usw. Die rein prozedurale Lösung ist noch die geschickteste in diesem Fall.

Nun nochmal alles als Unit zusammengefasst:

Delphi-Quellcode:
unit MyCrypt;

interface

uses Classes, DECUtil;

procedure Encrypt(ASource, ADest: TStream; const APassword: String; const AProgress: IDECProgress = nil); overload;
procedure Decrypt(ASource, ADest: TStream; const APassword: String; const AProgress: IDECProgress = nil); overload;

procedure Encrypt(const ASourceFileName, ADestFileName, APassword: String; const AProgress: IDECProgress = nil); overload;
procedure Decrypt(const ASourceFileName, ADestFileName, APassword: String; const AProgress: IDECProgress = nil); overload;

procedure SecureDeleteFile(const AFileName: String);

implementation

uses Windows, DECRandom, DECCipher, DECHash, DECFmt;

const
  ACipherClass: TDECCipherClass = TCipher_Rijndael;
  ACipherMode: TDECCipherMode = cmCTSx;
  AKDFClass: TDECHashClass = THash_SHA1;
  AKDFIndex: Cardinal = 1;
  AKDFSaltSize: Byte = 16;

procedure Encrypt(ASource, ADest: TStream; const APassword: String; const AProgress: IDECProgress = nil); overload;
var
  Salt,SessionKey: Binary;
begin
  Assert(ASource <> ADest, 'Encrypt(), ASource must be distinct to ADest');

  with ValidCipher(ACipherClass).Create do
  try
    Salt := RandomBinary(AKDFSaltSize);
    SessionKey := ValidHash(AKDFClass).KDFx(APassword, Salt, Context.MaxKeySize, TFormat_Copy, AKDFIndex);

    Mode := ACipherMode;
    Init(SessionKey);
 
    ADest.WriteBuffer(Salt[1], Length(Salt));

    EncodeStream(ASource, ADest, -1, AProgress);
  finally
    Free;

    ProtectBinary(SessionKey);
    ProtectBinary(Salt);
  end;
end;

procedure Decrypt(ASource, ADest: TStream; const APassword: String; const AProgress: IDECProgress = nil); overload;
var
  Salt,SessionKey: Binary;
begin
  Assert(ASource <> ADest, 'Decrypt(), ASource must be distinct to ADest');

  with ValidCipher(ACipherClass).Create do
  try
    SetLength(Salt, AKDFSaltSize);
    ASource.ReadBuffer(Salt[1], Length(Salt));
 
    SessionKey := ValidHash(AKDFClass).KDFx(APassword, Salt, Context.MaxKeySize, TFormat_Copy, AKDFIndex);

    Mode := ACipherMode;
    Init(SessionKey);
 
    DecodeStream(ASource, ADest, -1, AProgress);
  finally
    Free;

    ProtectBinary(SessionKey);
    ProtectBinary(Salt);
  end;
end;

procedure Encrypt(const ASourceFileName, ADestFileName, APassword: String; const AProgress: IDECProgress = nil); overload;
var
  ASource, ADest: TStream;
  ATempFileName: String;
begin
  ATempFileName := ChangeFileExt(ADestFileName, '.$$$');
  try
    ASource := TFileStream.Create(ASourceFileName, fmOpenRead or fmShareDenyNone);
    try
      ADest := TFileStream.Creare(ATempFileName, fmCreate);
      try
        Encrypt(ASource, ADest, APassword, AProgress);
      finally
        ADest.Free;
      end;
    finally
      ASource.Free;
    end;
    SecureDeleteFile(ADestFileName);
    RenameFile(ATempFileName, ADestFileName);
  except
    SecureDeleteFile(ATempFileName);
    raise;
  end;
end;

procedure Decrypt(const ASourceFileName, ADestFileName, APassword: String; const AProgress: IDECProgress = nil); overload;
var
  ASource, ADest: TStream;
  ATempFileName: String;
begin
  ATempFileName := ChangeFileExt(ADestFileName, '.$$$');
  try
    ASource := TFileStream.Create(ASourceFileName, fmOpenRead or fmShareDenyNone);
    try
      ADest := TFileStream.Creare(ATempFileName, fmCreate);
      try
        Decrypt(ASource, ADest, APassword, AProgress);
      finally
        ADest.Free;
      end;
    finally
      ASource.Free;
    end;
    SecureDeleteFile(ADestFileName);
    RenameFile(ATempFileName, ADestFileName);
  except
    SecureDeleteFile(ATempFileName);
    raise;
  end;
end;

procedure SecureDeleteFile(const AFileName: String);
var
  Stream: TStream;
begin
  if FileExists(AFileName) then
  begin
    Stream := TFileStream.Create(AFileName, fmOpenReadWrite or fmShareDeny);
    try
      ProtectStream(Stream);
    finally
      Stream.Free;
    end;
    DeleteFile(AFileName);
  end;
end;

initialization
  RandomSeed;
finalization
end.
Wir binden zusätzlich noch die Unit DECRandom mit ein um einen kryptographisch sicheren Zufallsgenerator zu benutzen. Dieser wird mit RandomSeed; so wie Borland's Randomize; beim Starten der Applikation zufällig initialisiert. Diese Initialisierung erfolgt per default mit der aktuellen Systemzeit und PerformanceCounter(). Dies ist eine Archillesferse des Ganzen und wenn man es sehr sicher haben möchte so muß man dies ändern. Im Allgmeinen ist es aber so das die Gesamtsicherheit erstmal immer vom gewählten Passwort abhängt und dies ist bei menschlich gewählten Passwörtern eh viel geringer als die Sicherheit der angewendeten Algorithmen.

Die Decyrpt() Procedures sind das Pendant zu ihren Encrypt() Procedures.

Man kann nun diese Beispiele immer mehr ausbauen. Zb. könnte man in den Streamfunktionen zusätzlich noch Daten über den verwendeten CipherMode, Cipherklasse, KDF Funktionstyp, Länge des verwendeten Salt usw. usw. als Header abspeichern und natürlich entsprechned auch wieder laden in der Decrypt() Procedure. Damit wird das System immer flexibler aber eben auch eventuell störanfälliger oder sogar kryptrographisch unsicherer. Man könnte auch am Ende des verschlüsselten Streams eine prüfsumme der Daten abspeichern damit man bei der Entschlüsselung die Daten und das Passwort auf Richtigkeit überprüfen kann. Für all dies finden sich in der DP aber schon Beispiele.

Gruß Hagen

PS: alle Sourcen habe ich mal eben so eingehackt und sind leider noch nicht real getestet. Sie dienen also erstmal nur als Beispiele.

Dezipaitor 3. Feb 2008 17:07

Re: DEC 5.1 wie benutzen?
 
Heftig, heftig. Ich hoffe du hast dir deinen Text auch lokal gespeichert :D Für den Fall der Fälle. Wäre schade, wenn er verloren geht.

Andere Frage: Welche Delphiversionen können die DEC verwenden?

delphin06 3. Feb 2008 17:11

Re: DEC 5.1 wie benutzen?
 
Ich sag nochmal danke für die umfangreiche Erklärung hier!

Um nochmal auf das Thema "deutsche Sprache" zurückzukommen...ich will jez nich großartig darauf rumreiten aber meiner Meinung nach ist solche "Slang"-Sprache nicht unbedingt so schlimm. Das ist nunmal so die Sprache befindet sich in einer ständigen Entwicklung. Das sieht man ja auch sehr stark an den vielen englischen Begriffen die zunehmend "eingedeutscht" werden.
Aber ich verstehe auch, dass das hier kein Chat ist und man so auch mal vernünftig deutsch sprechen sollte (um es nicht zu verlernen^^)
Diesen Chat-Slang gewöhnt man sich halt viel zu sehr an, weil man ja auch sehr viel damit zu tun hat in der heutigen Zeit. Da geht es dann nicht mehr um genaue Schreibweisen, sondern es muss möglichst kurz sein aber dabei immer noch verständlich, weil das Schreiben numal nicht so schnell geht wie das Sprechen ;)


Auf jeden Fall Danke an Luckie und Hagen für die Unit, die die Anwendung des DEC 5.1 nochmal deutlich zeigt. Es sind hier denke ich mal sehr viele Hobby-Programmierer (wie ich) und die sind halt nich alle solche Delphi Profis wie ihr. Ich bin schon zufrieden das ich so einigermaßen eigene Programme schreiben kann und das reicht mir auch. Man lernt hier in solchen Foren einfach das meiste. Und durch solche Anwendungsbeispiele wird das ganze auch für Leute wie mich verständlicher^^

Gruß

[EDIT] Respekt an Hagen. Wenn man sich das so durchliest könnte man denken man redet mit einem Kryptographie Professor (bist du das?^^). Wahnsinn

negaH 3. Feb 2008 18:06

Re: DEC 5.1 wie benutzen?
 
Doch Slang-Sprache ist sogar massiv schädlich meiner Meinung nach. Slang entsteht wenn sich Gang's bilden und diese sich von den Anderen separieren möchten. Was daran soll gut sein ? Und meistens wird ein solcher Slang aufgegriffen von zb. Gangster-Rap-Musik-Gruppen mit dem Anspruch das reale Leben damit widerzuspiegeln. Dabei geht es aber eigentlich nur darum sich auf seinem Markt zu positionieren, qausi Einschaltquoten zu machen. Unsere frühkindliche Psyche fällt exakt darauf rein. Meistens sollte man dann als Erwachsener von solchen Tricks geheilt sein aber immer öfters passiert das eben nicht. Einfach weil diese Art zu sprechen und damit auch zu denken im eigenen Lebensumfeld des privaten Konsums verankert wurde. Wir konsumieren nur noch das was Slang ist, was Lebensgefühl ohne inhaltlichen Sinn darstellt. Wir haben Manager, haben Facility Manager und wissen nicht das es der Hausmeister ist, wir kennen die Back-Factory dei dem jeder Englänger sich fragt, was ist das ? Ja, die Bäckerei von nebenan.
Ein Auto kaufst du weil es chick ist und nicht mehr weil es dich wirklich von A nach B fährt. Slang ist also nichts weiter als ein Werbeversuch und unnötig. Das ist so wie annodazumals als die Indianer in Amerika durch uns Weiße verdrängt wurden. Wenn wir nicht aktiv die deutsche Sprache pflegen dann stirbt sie aus, sie wird verdrängt. Und das ist das eigentliche Problem, was übrigbleibt ist eine so schnell zeitlich wechselnde Sprache, weil sie nur noch ein Modetrend ist, die aufgefüllt ist mit Slang, mit Kunstworten, rein aus kommerziellem Interesse, das am Ende sich keiner mehr mit dem anderen versteht.

Egal, wenn du begriffen haben solltest das ich in diesen Punkten intolerant bin dann solltest du so intelligent und auch höflich sein deinen Chat-Stil hier nicht zu benutzen.

Gruß Hagen

delphin06 3. Feb 2008 19:07

Re: DEC 5.1 wie benutzen?
 
Naja ich seh das ein bisschen anders. Du hast deine Meinung und ich meine und dann ist auch gut. Das soll ja nicht das Thema hier werden.

Gruß

Dezipaitor 3. Feb 2008 19:15

Re: DEC 5.1 wie benutzen?
 
Zitat:

Zitat von Dezipaitor
Andere Frage: Welche Delphiversionen können die DEC verwenden?


Luckie 3. Feb 2008 20:10

Re: DEC 5.1 wie benutzen?
 
Eventuell solltet ihr eure Slang-Diskussion im Offtopic-Bereich führen, weil es nicht ganz uninteressant ist oder doch per PN. Nur so viel von meiner Seite, im Internet hat man nicht allzuviele Möglichkeiten, Höflichkeit gegenüber anderen zu zeigen, deswegen finde ich sollte man doch auf seine Grammatik und Rechtschreibung achten, denn das ist eine Form von Höflicheit. Letztendlich sollte einem auch bewusst sein, dass man hier Bittsteller ist und von anderen etwas will und wenn ich mir erst wein Postinmg drei mal durchlesen muss, weil es ohne Punkt und Komma geschrieben wurde, dann sag ich mir auch, "Ich habe besseres zu tun als deine Postings zu entziffern und wenn du dir noch nicht mal die Mühe machst etwas auf die Rechtschreibung und Grammatik zu achten, warum sollte ich mir die Mühe machen zu anworten?"

negaH 3. Feb 2008 20:16

Re: DEC 5.1 wie benutzen?
 
Zitat:

Kurze Frage:
Sind die DEC Units closed source und nur für Freeware-Programme? Wie kam es denn dazu?
Welche Delphiversionen können die DEC verwenden?
DEC Part I ist OpenSource, einzigste Einschränkung ist das man die Courage hat und eventuell an einer dunkeln Stelle seiner Aboutbox oder Hilfedatei oder Readme.txt auf die Verwendung des DECs hinweist. Ich weiß das das viel verlangt ist und manchesmal nur sehr kompliziert umzusetzen geht ;)

Alle anderen Teile des DECs sind genau betrachtet garnicht existent ausserhalb meines Datenspeichers ;)
Ich habe speziell für die DP hier mal par prekompilierte Blibliotheken gepostet und diese hostet nun Luckie für mich. Nochmals danke.

Das DEC Part II nun closed Source ist hat ganz verschiedene Gründe. Als erstes mal das ich die Erfahrung machen musste das man DEC Part I unter dem eigenen Namen als eigene Leistung darstellte. Es gibt aber auch gegenteiliges zu berichten. Zum zweiten weil auf Grund meiner "Supportanfragen", und ich erhielt zweitweise bis zu 100 Mails pro Tag !!, ich feststellen musste das heutzutage Support heist "der kann doch für mich meine Probleme lösen, warum dann noch mal selber in den Sourcecode schauen". Und mit fast 98% Wahrscheinlichkeit war es dann so das garnichtmal der Fehler im DEC lag. Nee es ist sogar so das ich die EMails die ich erhalten habe, die sich auch wirklich auf Fehler im DEC bezogen, an einer Hand abzählen kann. Die Frage ist also: wenn ich meine Hobbyarbeiten veröffentliche was kommt dann auf mich zu ? Fast immer nur Zeitverbrauch, Arbeit und wenig hilfreiches Feadback. Nungut, es ist aber nun auch so das das Thema Kryptographie nicht jedermans Sache ist, das muß ich berücksichtigen.
Zum dritten: DEC ist eine Phase in meiner Entwicklung ;) Hört sich abgehoben an, meint aber das ich mich mit dem Thema Kryptographie nur so ca. 3-4 Jahre befasst habe und dann wusste ich eigentlich alles was ich wissen wollte und der Spaß war vorbei. Mein Interesse am Thema ist also gesättigt und es gibt Neues.
Zum Vierten: DEC sollte aus drei Teilen bestehen. Part I kennt ihr und enthält die symmetrischen Verfahren. Part II wäre nur eine Bibliothek gewesen um die nötigen mathematischen Primitive zu entwickeln. Also das Rechnen mit supergroßen Zahlen, Modulararithmetik, Elliptische Kurven usw. usw. Also alles was eher im Arithmetischen Sektor anzusiedeln wäre. Zusätzlich wären noch Supportfunktionen enthalten um später die verschiedenen asymmetrischen Verfahren wie RSA, EC, ElGamal, Diffie Hellman uvm. zu vereinfachen. Part III nun würde auf beide Teile aufsetzten und Standardprotokolle wie PKCS, PGP, IEEE usw. zu implementieren.
Also ziemlich viel Arbeit ohne das ich jemals damit mein Brot verdienen könnte. Denn vor par Jahren hatten nur wenige Experten überhaupt ein Bedürfnis nach Kryptographie. Und gerade bei der Implemntierung von solchen Protokolen wie PKCS oder PGP würde ich eine Arbeit machen die mir im Grunde widerstrebt. Warum sollte ich mit nicht kommerziellem Interesse solche kommerziell durchsetzten Protokolle implementieren von deren Umsetzung ich noch nichtmal überzeugt bin ? Besonders PKCS ist so ein Fall, aufgebläht, unsicher und verkompliziert.
DEC part II ist auch deshalb closed Source weil ich darin einige von mir entwickelte Optimierungen und Algorithmenverbesserungen implementiert habe. Es steckt viel Knowhow drinnen und einige implementierte Verfahren dürften auch durch Patente geschützt sein. Bei dieser Art der Kryptographie, speziell Elliptische Kurven usw. kann man sehr schnell unabsichtlich in Patentfallen geraten. Dieser "Markt" ist da sehr aggressiv und es gibt so einige Patente auf mathematisch absolut offensichtliche Verfahren/Verbesserungen auf die jeder auch mit par Minuten Nachdenken von selber kommt. Die Wahrscheinlichkeit ist also hoch das auch ich mir einige offensichtliche Optimierungen einfallen lassen habe die patentiert sein könnten. Ergo: closed Source, nur private Benutzung etc.pp.

DEC Part I sollte ab Delphi 4 compilierbar sein, einfach weil overloads und default Parameter benutzt werden. Nach oben wird die Grenze durch Borland bestimmt. Solange die sich an ihre Schnittstelle halten und abwärtskompatibel belieben sollte Part I ohne einen Fehler/Warnung kompilierbar sein.

DEC Part II kann von 2-3 Leuten vollständig kompiliert werden ;) Für Part II gibts prekompilierte Versionen für Delphi 5,6,7 und 2006/2007. Allerdings werde ich für 2006/2007 keine Distributation verteilen da ich diese Delphi Versionen nicht lizensiert habe.
Aber kompilierbar dürfte auch dieser Teil unter allen Delphi Version ab Delphi 5 sein.

Nach einiger Zeit habe ich mich dann entschlossen Part I und Part II zusammenzupacken und auf Luckie's Rechner abzulegen. Hintergrund war das immer wieder nach einer Bibliothek gefragt wurde mit der man möglichst effizient supergroße Zahlen rechnen kann. In den meisten Fällen ging es dabei wirklich nur um private Ambitionen, also einfach mal reinschnuppern, mal par Konstanten berechnen, mal RSA ausprobieren usw. Dabei geht es auch nicht darum ob man Part II als vollständigen Source vorsich hat, Mathematik geht auch ohne den Source zu haben.

Von Zeit zu Zeit beschäftige ich mich noch mit diesem Thema, meistens wenn es ganz neue Entwicklungen gibt oder auf Grund von Nachfragen zb. hier in der DP. Tja, das wars mit der Historie vom DEC ;)

Gruß Hagen

PS: achso ein weiteres Problem war es kompatible Mitstreiter zu finden. Fast alle "Experten" auf diesem Sektor sind hm sagen wir mal verknöchert/verbohrt und starke Individualisten, sowas wie ich halt :)

Dezipaitor 3. Feb 2008 20:43

Re: DEC 5.1 wie benutzen?
 
Das mit den Mitstreitern kenne ich von JWSCL. Ich glaube aber, dass es ein Delphi Problem ist. In C++ tummeln sich einfach mehr Experten, die Zeit haben.
Ich hab deshalb auch vor die JWSCL in COM (ActiveX) zu implementieren. Sie kann dann auch in VB und C++ einfach verwendet werden.

jorgos 4. Feb 2008 11:40

Re: DEC 5.1 wie benutzen?
 
Hallo zusammen,
ich habe mir das jetzt mal alles angetan, weil ich auch eine Möglichkeit suchte, Dateien zu verschlüsseln.
Vorab auch mal ein Lob und ein "Hut ziehen2" an Hagen.
Da kann einem schwindelig werden.

So jetzt mal ganz kurz.
Kann ich irgendwie prüfen, ob eine Datei bereits verschlüsselt ist, um interaktiv zu verschlüsseln,
wenn ich möchte (z.B. bei einem ganzen Verzeichnis)?

Wäre für eine Antwort dankbar

Viel Grüße
Jorgos

Luckie 4. Feb 2008 11:56

Re: DEC 5.1 wie benutzen?
 
Nein, es sei denn du markierst die Datei irgendwie selber, sei es durch eine Dateiendung oder durch eine Bytefolge am Anfang der Datei.

negaH 4. Feb 2008 12:31

Re: DEC 5.1 wie benutzen?
 
Wenn du deine Dateien mit einer eigenen Software verschlüsselst dann geht das sicherlich. So wie es Luckie schon andeutete.
Wenn du aber damit meinst das du erkennen möchtest ob eine beliebige Datei mit unbekannten Format verschlüsselt ist dann geht dies nur sehr eingeschränkt. Man kann verschlüsselte Dateien erkennen im Vergleich zu vielen anderen Dateiformaten. Aber zb. gepackte Dateien, Dateien mit fast zufälligen Inhalt, viele Binäreformate usw. würde man ebenfalls als potentiell verschlüsselte Dateien identifizieren. Ich selber habe schonmal versucht so ein System zu konstruieren das selbstständig diese Differenzierung erlernenen kann, Stichwort Neuronale Netze zb. Das klappte auch schon, allerdings wirft es eben solche Ausnahmen wie genannt immer in einen Topf.

Gruß Hagen

gammatester 4. Feb 2008 12:44

Re: DEC 5.1 wie benutzen?
 
Zitat:

Zitat von Luckie
Nein, es sei denn du markierst die Datei irgendwie selber, sei es durch eine Dateiendung oder durch eine Bytefolge am Anfang der Datei.

In der Regel gibt es allerdings starke Hinweise, daß eine Datei verschlüsselt ist: Wenn Du zB eine .TXT verschlüsselst und keine andere Extension vergibts, wird man (wenn nicht gerade der ECB-Modus verwendet wird) ziemlich stutzig, wenn nur Schrott drin steht. Wenn der Algorithmus/Modus (Wieso wird eigentlich in Deiner Unit defaultmäßig der proprietäre cmCFS8-Modus verwendet?) gut ist, ist die Datei auch praktisch nicht komprimierbar.

Wenn allerdings Zufall/"Schrott" o.ä. verschlüsselt wird, hast Du ein anderes Problem: Die entschlüsselte Datei ist auch mehr oder weniger zufällig, und Manipulationen sind nicht oder nicht sofort ersichtlich. Deshalb sollte man Dateiverschlüsselung in der Regel zusammen mit Authentizitäts-"Prüfsumme" und Entschlüsselung mit der entsprechenden Verifikation verwendet. Leider kennt DEC weder EAX noch HMAC, die für diese Zwecke eingesetzt werden. Und wie es aussieht, hat Hagen auch keine Absicht diese einzubauen.

Gruß Gammatester

negaH 4. Feb 2008 13:28

Re: DEC 5.1 wie benutzen?
 
wenn man den CipherMode cmCTSx/cmCTS8 benutzt kann man am Ende eine CMAC errechnen und abspeichern. Das ist vergleichbar mit den sich gerade in Standardisierung befindelichen Ciphermodis bei AES. cmCTSx/cmCTS8 sind prohibitär das ist richtig. Im Grunde sind es doppelt arbeitende CBC Modis auf Blockgröße oder Bytegröße Feedback. Sie arbeiten wie CBC indem sie die Daten mit dem Feedbackregister vor der Verschlüsselung des Blocks XOR verknüpfen. Nach der Verschlüsselung wird aber nun zusätzlich auch der verschlüsselte Datenblock mit dem Feedback Register XOR verknüpft. So entsteht eine Verknüpfung der Datenblöcke untereinander die 1. von Feedbackregister Startwert abhängt, 2. vom Passwort und dem daraus erzeugten Schlüsselstrom und 3. von den Daten der Nachricht selber da man ja das Verschlüsselungprodukt noch zusätzlich XOR Verknüpft. cmCTS? ist also fast eine Alles oder Nichts Verschlüsselung ohne Selbstsynchronsation. Ändert sich 1 Datenbit mitten in den verschlüsselten Daten so sind alle nachfolgenden Datenblöcke inklusive des aktuellen Datenblockes vernichtet, eg. nicht korrekt entschlüsselbar. Am Ende einer Verschlüselung/Entschlüsselung kann man mit Cipher.CalcMAC eine sogenannte Cipher-MAC errechnen und somit auf Datenintegrität testen. Wie oben angedeutet wird sich die so errechnet CMAC komplett unterscheiden wenn nur 1 Datenbit falsch übertragenm wurde. Ok, da die meisten Cipher mit zb. 8 Bytes Feedbackregster arbeiten ist diese CMAC auch meistens nur 64 Bit groß. Das Kollisionsrisiko im Vergleich zu eienr guten Hash-MAC ist also viel größer. Nutzt man aber zb. einen 16 Bytes Blockcipher so ist das identisch mit einer zb. MD5-HMAC. Aber mit dem Unterschied das diese CMAC Berechnung Performancetechnisch schon inklusive ist.

Stört man sich nicht daran das cmCTS? prohibitär ist und nicht selbstsynchronisierend so dürfte das eine gute Wahl sein, sowohl aus Sicherhsitsaspekten betrachtet wie auch aus Sicht der Performance. Aus kryptrographischer Sicht dürfte somit cmCTS? identisch zu den neueren Ciphermodis sein, eben nur mit dem Unterschied das DEC diesen Mode schon seit Jahren anbietet und AES sich noch in der Findungsphase befindet. (ich weiß das du, Gammatester, da eine andere Meinung vertrittst ;) )

Ein weiterer Unterschied, prohibitär natürlich, besteht im Padding. Das neuste DEC wechselt wenn es padden muß vom Blockorientierten Modus zum Byteorientierten Modus. Ich erachte dies für die sicherste Paddingmethode. Den Byteorientierten Modus, wie zb. cmCBC8,cmCTS8 usw. benutzt man schon seit langer Zeit um sehr kurze und hochsensible Daten zu verschlüsseln, sie sind also anerkannte Verfahren. Sie sind aber bei langen Nachrichten ineffizienter das sie ja zb. bei Blockgröße 16 einen Datenblock insgesamt 16 mal verschlüsseln. Nimt man nun einen anerkannten Blockmodus wie CBC und verschlüsselt den letzten zu kurz geratenen Datenblock im dazu vergleichbaren Byteorientierten Ciphermode so hat man eine gute Methode für ein Padding. Neben viele anderen Vorteilen ergibt sich der Vorteil das man Daten die kürzer sind als die Blockgröße des Ciphers autom. immer im 8Bit Feedbackmodus verschlsüselt, da dieser 1. Datenblock ja auch gleichzetig der zu paddende Datenblock ist. Somit benutzt dieses Paddingschemata auch bei sehr kurzen Datenmengen den sichersten Modus. In keinem der Fälle kommt es zu einer Datenexpansion bei der Verschlüsselung, was enorm von Vorteil ist. Zudem braucht man dann auch nicht mehr spezielle und komplexere Chiphermodis zu impolenetieren das das System meistens immer einen Blockorientierten und Byteorientierten Feedbackmodus anbieten kann.

Also, das was ich im DEC implementiert habe hat meiner Meinung nach sehr wohl ein kryptographisch sauberes Fundament, nur mit dem Unterschied das DEC sowas schon seit längerer Zeit anbietet und die neueren Standards längst noch nicht in der Praxis angekommen sind. Verfolgt man den AES Zertifizierungsablauf bei den Ciphermodis über längere teit so wird man feststellen das von den vielen vorgeschlagenen Ciphermodis sehr viele in kürzester Zeit als unsicher bewiesen wurden. Das Komen und Gehen in diesem Sektor ist nach meinem Gefühl viel stärker als bei der Auswahl geeigneter Verschlüsselungsalgorithmen, also beim AES Rijndael. Das suggeriert wenig Vertrauen.

Ich werde diese Modis noch einbauen, mit Sichereit, aber erst wenn diese neuen Modis in der Praxis auf breite Akzeptanz gestoßen sind. Das heist ganz im Besondern das ich eben nicht EAX einbauen werde solang nur spezielle Produkte diesen unterstützen, womöglich nur diejenigen Produkte die den EAX entwickelt und vorgeschlagen haben.

Gruß Hagen

jorgos 4. Feb 2008 13:50

Re: DEC 5.1 wie benutzen?
 
Zitat:

Zitat von Luckie
Nein, es sei denn du markierst die Datei irgendwie selber, sei es durch eine Dateiendung oder durch eine Bytefolge am Anfang der Datei.

Hallo zusammen,

erstmal Vielen Dank für die schnellen Antworten.

Ich habe mir den Source der DLL "MyCrypt" kopiert.

Ich meine bei diesem Verfahren.
Nicht, wenn eine Datei mit anderen Systemen verschlüsselt ist.

Wie kann ich denn
Zitat:

eine Bytefolge am Anfang der Datei
einbauen.
Hat da jemand eine Idee ? :oops:
Mit Sicherheit. :drunken:

Kann mir jemand einen Tipp geben.

Wäre sehr Dankbar.

Viele Grüße
Jorgos

negaH 4. Feb 2008 13:51

Re: DEC 5.1 wie benutzen?
 
Zitat:

n der Regel gibt es allerdings starke Hinweise, daß eine Datei verschlüsselt ist: Wenn Du zB eine .TXT verschlüsselst und keine andere Extension vergibts, wird man (wenn nicht gerade der ECB-Modus verwendet wird) ziemlich stutzig, wenn nur Schrott drin steht. Wenn der Algorithmus/Modus (Wieso wird eigentlich in Deiner Unit defaultmäßig der proprietäre cmCFS8-Modus verwendet?) gut ist, ist die Datei auch praktisch nicht komprimierbar.
Wird cmCTS? im Zusammenhang mit einem randomisierten InitVector oder besser noch mit einer randomisierten KDF, wie oben im Bespiel gezeigt benutzt, dann trifft deine Aussage zu. Die Daten verhalten sich wie unkomprimierbarer Zufall.

Solche Daten lassen sich fats garnicht von Zufallsdaten oder komprimierten Daten unterscheiden. Dazu müsste man auf die Header komprimierter Dateien testen. Nun entsteht logisch betrachtet eine Argumentationskette wenn man sagt

1.) es gibt verschlüsselte Daten die vorher komprimeirt wurden
2.) es gibt komprimierte Daten die vorher verschlüsserlt wurden

Solche Daten kann man nicht differenzieren. Eine verschlüsselte Datei kann komprimiert sein und eine komprimierte Datei mit ZIP Header kann auch verschlüsselt sein. Wie soll man das dann unterscheiden können ?

Man könnte auch sagen, es gibt Dateien mit teilweise verschlüsselten Daten. Diese besitzen durchaus Header etc.pp. die in einer Mustererkennung auf Gesamt-Dateibasis identifizierbar sind. Damit würden diese Dateien eben nicht mehr als verschlüsselte Daten erkannt.

Man kann Verschlüsselung also nur im Rahmen eines bekannten Kontextes erkennen und dafür gibt es vielzuviele Dateiformate bzw. verschiedene Verschlüsselungen.

Das gesamte Problem lässt sich bis auf einen Punkt reduzeren -> Wenn man Daten unterhalb einer informationstheoretischen Rauschgrenze verstecken kann dann kann es kein Verfahren geben das Daten nach verschlüsselt und unverschlüsselt differenzieren kann wenn nicht alle Rahmenbedingungen bekannt sind, dazu gehört im Besondenen das Paswort. Und exakt sowas gibt es, nennt sich Steganographie. Deshalb erachte ich die Wissenschaft der Steganographie, das Verstecken von Daten unterhalb der informationstheoretischen Rauschgrenze, auch als eine Wissenschaft der Kryptographie.
Dh. ohne das benutzte Passwort für den steganographsichen Algortihmus kann man die Daten nicht mehr aus der informationstheoretischen Rauschgrenze extrahieren, das ist ja der Sinn der Steganographie. Ergo kann mna auch nicht erkennen ob bei diesen Daten eine Verschlüsselung angewendet wurde.

Fazit: man kann verschlüsselte Daten nicht identifizieren, das geht nicht da wir die informationstheoretische Rauschgrenze nicht durchbrechen können ohne das Passwort zu kennen, das hat Heisenberg schon mit seiner Unschärferelation bewiesen.

OffTopic: dieser "Beweis" zeigt wie dämlich die politischen Forderungen eines Überwachungsstaates sind.

Gruß Hagen

negaH 4. Feb 2008 14:03

Re: DEC 5.1 wie benutzen?
 
@Jargos:

bei ADest.WriteBuffer(Salt[1], Length(Salt)); in Encrypt() kannst du vor oder danach eigene Daten abspeichern. Die musst du natürlich in Decrypt() auch wieder rauslesen. Also eigene Datenmenge abspeichern und exakt gleiche Datenmenge vor dem Entschlüsseln wieder rauslesen. Du musst nur die TStream basierten Prozeduren abändern.

Gruß Hagen

PS: beachte das diese Daten dann unverschlüsselt sind. Möchtest du dies nicht dann kannst du auch ein zweifaches .EncodeStream(ASource, ADest,..) einbauen. das ginge dann so

Delphi-Quellcode:

with ...Create do
try
  ...blabla Init Sequenz

  SetLength(AData, Cipher.Context.BufferSize * x);
  AData := EncodeBinary(AData, TFormat_COPY);
  ADest.WriteBuffer(AData[1], Length(AData));
  EncodeStream(ASource, ADest, ....);
finally
  Free;
end;
Nur musst du beachten das die Anzahl an Bytes in AData exakt ein Mehrfaches der Cipher.BufferSize sind um ein vorzeitiges Padding zu vermeiden. Du verschlüsselt als so als wenn in ASource ein Header von dir vor den eigentlichen Daten drinnenstehen würde.

gammatester 4. Feb 2008 14:20

Re: DEC 5.1 wie benutzen?
 
Zitat:

Zitat von negaH
wenn man den CipherMode cmCTSx/cmCTS8 benutzt kann man am Ende eine CMAC errechnen und abspeichern.

[SNIP]

Am Ende einer Verschlüselung/Entschlüsselung kann man mit Cipher.CalcMAC eine sogenannte Cipher-MAC errechnen und somit auf Datenintegrität testen. Wie oben angedeutet wird sich die so errechnet CMAC komplett unterscheiden wenn nur 1 Datenbit falsch übertragenm wurde. Ok, da die meisten Cipher mit zb. 8 Bytes Feedbackregster arbeiten ist diese CMAC auch meistens nur 64 Bit groß. Das Kollisionsrisiko im Vergleich zu eienr guten Hash-MAC ist also viel größer. Nutzt man aber zb. einen 16 Bytes Blockcipher so ist das identisch mit einer zb. MD5-HMAC. Aber mit dem Unterschied das diese CMAC Berechnung Performancetechnisch schon inklusive ist.

Zuerst war ich verwirrt, weil CMAC das "standardisierte" OMAC1 ist, aber im DEC-Quellcode stehts dann ja drin (wenn man weiß, was man nachsehen soll), und offensichtlich gibts diese "CMAC" praktisch kostenlos für alle Modi bis auf EBC. Wäre doch eine gute Idee für in Luckies Unit, diese Prüfbytes neben Salt und Ciphertext mit abzuspeichern und beim Entschlüsseln zu verifizieren.

Zitat:

Zitat von negaH
Also, das was ich im DEC implementiert habe hat meiner Meinung nach sehr wohl ein kryptographisch sauberes Fundament, ...

Ich habe auch ich nicht unterstellt, daß dem so wäre, und wie man sieht ist ja auch eine Authentizitäts- / Verifikationsmöglichkeit vorhanden, und nur das war ein Punkt meines Beitrags.

Gruß Gammatester

negaH 4. Feb 2008 14:37

Re: DEC 5.1 wie benutzen?
 
;) hey, ich weiß wer du bist und demzufolge weiß ich auch wie du es gemeint hast, ich bin zu keiner Zeit davon ausgegangen das ich mich angegriffen fühlen müsste ;)

Ja, man kann das oben noch einbauen, ginge sogar sehr einfach. Das Thema habe ich aber unter -> Es gibt Verbesserungen und hier in der DP schon als Source zu finden, abgehackt. Ich muß halt immer einen Kompromiß anstreben, zwischen dem was ich hier als Beispiele poste und noch verständlich ist und dem was alles möglich wäre. Kryptographie ist deshalb sicher weil man das bestehende Wissen auch begriffen hat, man weiß es also. Erkläre ich zuviel kann mir keiner mehr folgen und man wird auf gut Glauben das wiederkauen wa ich an Beispielen gepostet habe ohne es verstanden zu haben. Das ist dann keine Kryptographie mehr, leider.

denoch hier die Änderungen mal angedeutet:

Delphi-Quellcode:
procedure Encrypt(ASource, ADest: TStream; ...blabla); overload;
var
  ... blabla
  MAC: Binary;
begin
  with ... do
  try
    ...blabla Initialisierung hier

    EncodeStream(ASource, ADest, -1);

    MAC := CalcMAC(TFormat_COPY);
    ADest.WriteBuffer(MAC[1], Length(MAC));
  finally
    Free;
    ....bla
    ProtectBinary(MAC);
  end;
end;

procedure Decrypt(ASource, ADest: TStream; ...blabla); overload;
var
  ... blabla
  MAC: Binary;
begin
  with ... do
  try
    ...blabla Initialisierung hier

    DecodeStream(ASource, ADest, ASource.Size - ASource.Position - BufferSize);

    SetLengh(MAC, BufferSize);
    ASource.ReadBuffer(MAC[1], Length(MAC));
    if MAC <> CalcMAC(TFormat_COPY) then
      raise Exception.Create('invalid decryption data maybe modifyed or please verify your password');
  finally
    Free;
    ....bla
    ProtectBinary(MAC);
  end;
end;
ABER VORSICHT! Die Berechnung der CMAC hängt stark vom verwendeten Ciphermode ab. Im Grunde ist diese CMAC nur dann aussagekräftig wenn im cmCTS?/cmCFS? Modus gearbeitet wird. Im cmCBCx Modus kann man eine CMAC berechnen lassen nur wird diese auf Grund der Selbstsynchronisation des CBC Modus eben nicht aussagekräft sein.
Der cmCTS?/cmCFS? Modus enthält quasi einen Lawineneffekt. Ein falsches Bit lösste eine Lawine aus die alle nachfolgenden Bits verändert, bis zum Ende der Verschlüsselung und der Berechnung des CMAC. Die Selbstsynchrnisation ist zerstört dafür ergibt sich quasi sowas wie eine Prüfsumme über alle Datenbits. Dies trifft aber auf alle selbstsynchronisierenden Modis nicht zu.

So. Und wieder die Verständlichkeit dieses Threades verschlechtert ;)

Gruß Hagen

delphin06 4. Feb 2008 16:36

Re: DEC 5.1 wie benutzen?
 
Ich möchte hier kurz nochmal was anderes einwerfen und zwar bekomme ich bei Delphi 2007 sehr viele Warnungen:

Delphi-Quellcode:
[DCC Warnung] DECData.pas(3948): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3948): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3949): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3949): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3950): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3951): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3951): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3951): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3952): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3952): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3954): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3954): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3954): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3954): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3955): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3955): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3957): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3957): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3958): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3958): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3958): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3958): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3959): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3959): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3959): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3962): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3962): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3963): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3963): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3963): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3963): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3964): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3964): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3964): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECData.pas(3964): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECHash.pas(2128): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECHash.pas(2130): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECHash.pas(2133): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECHash.pas(2134): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECHash.pas(2168): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECHash.pas(2170): W1012 Konstantenausdruck verletzt untere Grenzen
[DCC Warnung] DECHash.pas(2172): W1012 Konstantenausdruck verletzt untere Grenzen
Ich weiß nicht ob die schlimm sind, deshalb möchte ich nur mal eben nachfragen. Ich hab es immer lieber, wenn gar keine Warnungen auftreten.

negaH 4. Feb 2008 17:17

Re: DEC 5.1 wie benutzen?
 
In den Projektoptionen -> Compiler -> alle Laufzeitfehlerüberprüfungen wie RangeChecks usw. ausschalten. Das sollte Standard sein. Die gemeldeteten "Fehler" sind in Wahrheit keine, dh. alles ist richtig. Man könnte jetzt im Projekt/Units selber diese Überprüfungen per Compilerswitches deaktivieren, aber auch das hat Nachteile.

Also {$R-} am Anfang der Units einfügen oder alternativ in Ver.inc diesen Switch aufnehmen um damit in allen DEC Units diese Überprüfung auszuschalten.

Gruß Hagen

delphin06 4. Feb 2008 17:22

Re: DEC 5.1 wie benutzen?
 
OK, Danke.

jorgos 5. Feb 2008 09:09

Re: DEC 5.1 wie benutzen?
 
Hallo zusammen,

erstmal Danke für die Tipps.
Ich habe so einigermaßen umgesetzt, was ich wollte.

Delphi-Quellcode:
Adata := 'teststring123';
....
ADest.WriteBuffer(Salt[1], Length(Salt));
EncodeStream(ASource, ADest, -1, AProgress);

...
ADest.WriteBuffer(Adata[1], Length(Adata));
....
Hier schaffe ich es, die Daten ans Ende der Datei anzuhängen.
Ist im Klartext (Erstmal egal).

Aber wie schaffe ich es, diese Daten beim decodieren wieder auszulesen.
Bin bei allen Versuchen gescheitert.

Delphi-Quellcode:
... habe hier versucht am Ende der Datei + lenge adata, die Daten auszulesen.
ASource.ReadBuffer(adata[1], Length(Salt) + length(adata));
form1.Label1.Caption := adata;
Aber das geht nicht (werdet ihr schon gesehen haben :oops: )

Hat jemand noch einen Wertvollen Tipp für mich

Würde mich freuen.
Vielen Dank nochmal
Jorgos

Luckie 5. Feb 2008 09:17

Re: DEC 5.1 wie benutzen?
 
Du musst natürlich zu erste an die Stelle in der Datei springen, an der sich die Daten befinden. Deswegen ist es günstiger diese Daten an den Anfang der Datei zu schreiben. Da kannst du sie einfach lesen und wenn du sie gelesen hast, kannst du einfach den Rest lesen, ohne den Dateizeiger hin und her bewegen zu müssen.

negaH 5. Feb 2008 10:51

Re: DEC 5.1 wie benutzen?
 
Nicht nur das sondern du musst auch die Größe in Bytes deiner AData mit speichern. Wenn AData also in der Länge variable sein kann dann kannst du diese nur exakt wieder auslesen wenn du deren vorherigen Länge weist. Es sei denn AData hat immer die gleiche Länge, dann kannst du das hardcoded machen, quasi wie im Beispiel mit dem Salt.

Gruß hagen

jorgos 5. Feb 2008 15:47

Re: DEC 5.1 wie benutzen?
 
Yepp,
das war´s.
Habe alle Info´s, die ich brauche.
Danke an alle.

Jorgos


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:31 Uhr.
Seite 1 von 2  1 2      

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