![]() |
Einmal mit DEC Ver- und Entschlschlüsseln funktioniert nicht
Nachdem ich seit kurzem (gestern :D) DEC benutze, gibt es ein Verschlüsselungs und Enschlüsselungsproblem. Einmal mit DEC En/DeCoded ergibt leider nicht die Ausgangsdatei.
Hier meine Vorgehensweise: Zuerst erstelle ich eine TStringList (ohne ""): Zitat:
Delphi-Quellcode:
fileCatalog{<== Die StringList}.Text := EnCode(frmPassword.Password, fileCatalog.Text);
fileCatalog.SaveToFile(sdSave.FileName);
Delphi-Quellcode:
Wenn ich die Dann lade:
function TfrmManager.EnCode(key, text: string): string;
begin with TCipher_Rijndael.Create do try Mode := cmCBCx; Init(THash_SHA1.KDFx(key, RandomBinary(16), Context.KeySize)); Result := EncodeBinary(text); finally Free; end; end;
Delphi-Quellcode:
fileCatalog.Text := DeCode(frmPassword.Password, fileCatalog.Text);
Delphi-Quellcode:
Dann kommt nicht das Entprodukt raus.
function TfrmManager.DeCode(key, text: string): string;
var Salt : Binary; begin Salt := RandomBinary(16); with TCipher_Rijndael.Create do try Mode := cmCBCx; Init(thash_sHA1.KDFx(key, Salt, Context.KeySize)); Result := DecodeBinary(text); finally Free; end; end; Ich kann außerdem ausschließen, dass die Datei (unverschlüsselt) fehlerhaft ist. Also ist sie innerhalb des DeCode/Encode-Blocks. Vor dem Verschlüsseln: Zitat:
Zitat:
[edit]Öhm, aber jetzt ist etwas in der letzten "Zeile" kaputt ...[/edit] |
Re: Einmal mit DEC Ver- und Entschlschlüsseln funktioniert n
versuche mal
Delphi-Quellcode:
in .Decode() dann das gleiche.
function TfrmManager.EnCode(key, text: string): string;
begin with TCipher_Rijndael.Create do try Mode := cmCBCx; Init(THash_SHA1.KDFx(key, RandomBinary(16), Context.KeySize)); Result := EncodeBinary(text, TFormat_MIME64); // <------ finally Free; end; end; Das Problem ist nämlich das der Datentyp "Binary" im Grunde ein simpler LongString ist. TStringList arbeitet intern aber mit PChar. Dh. ein LongString der ein Zeichen #0 -> Null-Terminator -> mitten drinnen enthält wird an dieser Stelle durch TStringList abgeschnitten. Man kann also in einem LongString binäre Daten speichern muß aber höllisch aufpassen das man diesen String nicht als normalen String betrachtet und eben nicht zb. einer TStringList zuweist. Bei deiner Zuweisung TStringList.Text := Encode(); gehen also Daten verloren da die RTL/VCL/TStringList das abschneidet wenn in den Daten ein #0 Zeichen vorkommt. Desweiteren konvertiert die TStringList -> TStringList.Text := XYZ, Methode auch die Zeichen #10 und #13 -> Line Feed und Carrige Return implizit. Aus dem binärem Datenstring werden also die Zeichen durch die TStringList entfernt (besonders wenn sie doppelt vorkommen) und stattdessen der String gesplittet in TStringList.Strings[0] .. TStringList.Strings[1] ... TStringList.Strings[x] abgespeichert. Wenn man nun mit XYZ := TStringList.Text diesen String wieder abfragt baut TStringList wieder #10#13 Zeichen in das Resulat rein. Diese stimmen dann aber nicht mehr mit dem Original Binärem Wert überein. Du hast also über TStringList den binären Wert ohne das du es merkst verändert. Das ein solch veränderter Wert nun nicht mehr den originalen entschlüsselten Text ergeben kann ist jetzt wohl logisch, oder ? Übrigens, unter den 1000'enden EMail-Support-Anfragen die ich bekommen habe ist es dieser Fehler der in 90% aller Fälle gemacht wurde. Also ein typischer Anfängerfehler ;) [edit] Ich habe sogar schon zwei EMail-Templates (in deutsch und englisch) angelegt um mir die Arbeit bei solchen Supportanfragen zu vereinfachen ;) [/edit] Um das zu verhindern benutzt du statt dem binärem Datenformat eine Konvertierung in ein lesbares stringkompatibles Datenformat. Wie oben eben das Indernett MIME Base 64 Format. Normalerweise macht es aber auch keinen Sinn, so wie du es machst, einer TStringList einen Binären Wert zuweisen zu wollen. Das was du da machst ist im Grunde also "unclever" (vorsichtig ausgedrückt). Zum Glück machen alle DEC Funktionen diese Konvertierungen inklusive, du musst es ihnen nur sagen. Statt MIME64 könntest du auch mal TFormat_HEX oder TFormat_ESCAPE versuchen. Gruß Hagen PS: um auf dieses Verhalten hinzuweisen habe ich im DEC 5.1 eben den Datentype "Binary" eingeführt. Denn wenn man dieses Verhalten kennt ist der "Mißbrauch" eines LongStrings/Strings als boinärer Datenkontainer im Grunde eine gute Wahl. Ich hätte auch einen eigenen dynamischen Datentyp -> array of Byte -> benutzen können. Dieser wäre dann aber eben nicht mehr kompatibel zu LongStrings gewesen und konzeptionell die Schnittstellen im DEC unnötig verkompliziert. Es ist also eine Kompromiß-Entscheidung meinerseits gewesen das so und nicht anders zu machen ;) |
Re: Einmal mit DEC Ver- und Entschlschlüsseln funktioniert n
So und nun noch zum Salt.
Ändere deine Methoden ab:
Delphi-Quellcode:
Du musst also den Passwort-Salt mit in deine Daten reinpacken, logisch sonst hast du ja zur Dekodierung nicht die gleiche Ausgangsituation. Die Verwendung eines Passwort-Salts mit einer KDF ist aber eine immer zu empfehlende Praxis, schützt sie doch perfekt das Passwort vor Brute Force Angriffe. Also lieber einen leicht komplizierteren Weg gehen dafür aber um vieles sicherer als ohne dieses Salt.
function TfrmManager.Encode(const Key: String; const Text: String): String;
var Salt: Binary; begin with TCipher_Rijndael.Create do try Mode := cmCBCx; Salt := RandomBinary(16); Init(THash_SHA1.KDFx(Key, Salt, Context.KeySize)); Result := TFormat_MIME64.Encode(Salt + EncodeBinary(Text)); finally Free; end; end; function TfrmManager.Decode(const Key: String; const Text: String): String; var Data: Binary; begin with TCipher_Rijndael.Create do try Mode := cmCBCx; Data := TFormat_MIME64.Decode(Text); Init(THash_SHA1.KDFx(Key, Copy(Data, 1, 16), Context.KeySize)); Result := DecodeBinary(Copy(Data, 16, MaxInt)); finally Free; ProtectBinary(Data); end; end; Achtung: obige Sourcestücken habe ich nicht getestet ! (Indizes in Copy()) Gruß Hagen |
Re: Einmal mit DEC Ver- und Entschlschlüsseln funktioniert n
Hi Hagen ;)
Danke für diesen "Bugreport" :D Also war meine Vermutung (die ich nicht notiert hatte), dass etwas beim "Format" fehlt richtig gewesen... Eine Frage zum "Salt": Was bringt mir das? Warum wird es dadurch so sicher? Zitat:
[quote="negaH"]
Delphi-Quellcode:
Die "16" ist die Zahl im "RandomBinary"?
Result := DecodeBinary(Copy(Data, 16, MaxInt));
Zitat:
[edit]Der 2. Paramter musste beim Copy "17" sein ;)[/edit] |
Re: Einmal mit DEC Ver- und Entschlschlüsseln funktioniert n
Zitat:
Das Resultat dieser Berechnung kann auf Grund der Eigenschaften der Hashfunktion nicht mehr zurückgerechnet werden in Passwort + Salt. Da der Salt zufällig ist würde bei dieser Berechnung jedesmal ein anderer Sessionkey rauskommen, quasi-zufällig, obwohl man das gleiche Passwort benutzt. Nun ist es in der Realität so das man oft das gleiche Passwort wiederverwendet und damit ganz verschiende Sachen verschlüsselt. Benutzt man das Passwort direkt als Key so könnte man in einem unsicheren Verfahren eventuell dieses Passwort direkt berechnen, schwups hat man den Schlüssel geknackt. Das führt dann dazu das durch das schlechte Benutzerverhalten der Angreifer über die "unsichere Verwendung auf WEB Seite X, das Passwort knackt und selbst auf der absolut sicheren und gute konstrukierte WEB Seite Y Zugriff auf die Konten des Benutzers erlangt". Das heist der Benutzer nutzt das gleiche Passwort an unterschiedlichen Stellen und die schwächste Stelle komprimiertiert dadurch das Gesamtsystem. Wenn also Seite X scheiße mit den Daten umgeht so wird dadurch auch Seite Y kompromitiert wenn der Benutzer das/die selben Passwörter benutzt. Das ist heutzutage oft der Fall. Die Salt-Methode verhindert nun das man durch einfache Brute Force Attacke das Passwort berechnen kann. Wir gehen davon aus das der Angreifer den Verschl. Algo. X knacken kann, er kann also aus einer verschl. Nachricht dieses Verfahrens den benutzten Schlüssel ermitteln. Würden wir keinen Salt+Einwegfunktion benutzen so hätte er direkt das Passwort geknackt. Wenn wir aber obige Methode -> KDF -> Key Derivation Function -> Schlüssel-Ableitungs-Funktion benutzen dann hat der Angreifer NUR diesen EINEN Sessionkey geknackt. Eine zweite Datei mit gleichem Passwort und Verfahren würde auf Grund des Zufallssalts ja wiederum einen anderen Sessionkey erzeugen. Der Angreifer MUSS erneut die Nachricht komplett knacken um nun diesen EINEN einmalig verwendeten Sessionkey zu knacken. Er muss also alle Nachrichten einzeln knacken. Wenn nun der Aufwand dieses Prozeses > 1 ist dann bedeutet dies das er durch unsere KDF also X Dateien * Aufwand Knacken benötigt statt nur 1 Datei Knacken und X-1 Dateien sofort entschlüsseln zu können. Wir erhöhen also mathem. beweisbar den Aufwand des Knackens beim Angreifer. Da der Salt 16 Bytes = 128 Bit = 2^128 Kombinationen hat, also sehr groß ist, verhindern wir das wir quasi doppelte Sessionskeys erzeugen, einfach weil die Wahrscheinlichkeit mit 1/2^128 enorm gering ist. Wir haben also aus unserem EINEM Passwort das wir X mal verwenden wollen auf sichere Art&Weise X gute Sessionkeys erzeugt. Nur derjenige der das Passwort und die X Salts kennt kann diese X Sessionkeys reproduzieren. Wir schützen also das reale Passwort des Benuitzers und erhöhen noch den Aufwand für einen Angreifer. Denoch: eine KDF schützt nichts besser wenn der Angreifer direkt das Passwort per Brute Force Attacke knackt (er kennt also den Salt). Dh. eine KDF ist kein "Ausgleich" dafür das man nun schlechte Passwörter benutzen kann, sie erhöht nur die Angriffskomplexität wenn man ein Passwort mehrmals verwendet, und das ist weitaus besser als das Passwort direkt mehrmals zu benutzen. Gruß Hagen |
Re: Einmal mit DEC Ver- und Entschlschlüsseln funktioniert n
Ah Verstanden ;)
Coole Idee die da hintersteckt. Nur gibt es da ein Problem: Wie kommt man wieder an das (den?) Salt ran? Klar über Data, aber wenn der Angreifer das Passwort kennt und den Algorithmus, dann kennt er auch Date = Salt oder denke ich da gerade falsch? |
Re: Einmal mit DEC Ver- und Entschlschlüsseln funktioniert n
Genau das Frage ich mich auch immer. Was, wenn der Angreifer zum Beispiel ein Passwort in Erfahrung bringen will, wo der Salt und der Hashwert in einer Datenbank gespeichert sind. Der Angreifer kennt das verwendete Hashverfahren, weiß den Salt und den Hash des mit dem Salt verknüpften Passworts. Zusätzlich verfügt er über ein Wörterbuch. Es ist unmöglich für jeden Saltwert ein Wörterbuch berechnet zu haben. Aber wozu auch?
Statt jedes Wort aus seiner Datenbank so zu verwenden, muss er es doch einfach nur mit dem Salt verknüpfen und die Hashfunktion darauf anwenden. Er benötigt lediglich mehr Rechenaufwand. :gruebel: |
Re: Einmal mit DEC Ver- und Entschlschlüsseln funktioniert n
Jo, ein Wörterbuch->Dictionary Attack zählt zu den Brute Force Attacken und soll durch Vorrausberechnungen die Onlinezeit zum Knacken reduzieren. Das erzeugt quasi Kosten an anderer Stelle ;)
Rechne mal nach -> 2^128 Salts * 2^128 Passwörter, beides mit 16 Bytes und der Hashwert mit 16 Bytes noch dazu ! Das sind dann 47428439751604713645494675459558567056699385719046 3750305618264096412179005177856 Bytes an Daten. Na dann viel Spaß mit dem Brennen von Trillionen von Trillionen von Daten CDs ;) Man kann also auf Grund der Datenmenge kein komplettes 1 zu 1 Dictionary erzuegen, es dauert zu lange und benötigt viel zu viel Speicher, so viel Speicher das mit heutigen Lesegräten alleine das Auffinden eines Datensatzes zu lange dauern würde. Ergo: man benötigt ein cleveres Dictionary, und das gibts sogar, mit Namen "Rainbow Tables". Aber auch hier konnte bewiesen das bei guten Passwörtern es nicht mehr funktioniert, sprich unpraktikabel ist. Aber am besten ist: es funktioniert nur mit puren Passwörtern, benutzt man noch einen 128 Bit Salt dann benötigt man nicht mehr nur 1 solches Dictionary sondern 2^128 = 340282366920938463463374607431768211456 Stück davon. Der Salt ist also auch sehr gut geeignet um solche schnelleren Brute Force Attacken per Dictionaries unmöglich zu machen ;) Der Angreifer muß also immer online seine Attacke durchführen, eine Attacke die theoretisch immer bei jedem Verfahren möglich ist, aber mathematisch beweisbar so komplex gemacht wurde das sie praktisch undurchführbar wird. Das ist der Sinn von guter Kryptographie. Die Frage die du dir stellen solltest ist also: Kanst du dir einen Berg von DVDs vorstellen die alle im Gesammten 47428439751604713645494675459558567056699385719046 3750305618264096412179005177856 Bytes speichern ? Ich kann es nicht ;) Angenommen pro DVD sind 1Gb gespeichert und 1 DVD wiegt nur 1 Gramm dann haben wir einen Berg von DVDs der 43135914667441023671467224139231409077819431076064 9159697657763 Tonnen wiegt. 5,972 Tausend Trillionen Tonnen wiegt die Erde. Unser Berg von DVDs die nur 1 Gramm wiegen würde 72230265685601178284439424211706981041 mal schwer als die Erde sein. Die Sonne ist 332950 mal schwerer als die Erde, unser Berg von DVDs die nur 1 Gramm wiegen wäre also 216940278376937012417598510922682 mal schwerer als unsere Sonne !! Die Sonne enthält 2^190 Atome und das gesamte Universum laut Bruce Schneier enthält 2^265 Atome wenn es insich geschlossen ist (wovon wir ausgehen können) und wir die Dunkle Materie vernachlässigen (die ca. 90% ausmacht). Die Sonne ist also ein 2^175'tel unseres Universums, wenn wir mal ein Auge fest zudrücken und Pi*Daumen rechnen. Die obige Zahl 216940278376937012417598510922682 ist pi*daumen 2^108, wir können also ohne Untertreibung sagen Unser Berg von 1 GB DVDs die jeweils 1 Gramm wiegen um 47428439751604713645494675459558567056699385719046 3750305618264096412179005177856 Bytes an Daten zu speichern wiegt dann ein 2^67'tel unseres sichtbaren Universums. Das wären viele viele Schwarze Löcher. Kannst du dir jetzt irgend jemanden vorstellen der in der Lage wäre diesen Berg von DVDs zu brennen ? ;) hast du jetzt eine konkretere Vorstellung was es heist wenn ein Hacker meint: Ach nur par 128 Bit Salts und par 128 Bit Passwörter da machen wir doch eine Wörterbuch Attacke und bauen uns eine MS-SQL Datenbank mit allen Hashwerten ;) Gruß Hagen PS: ich könnte mich übrigens um par Bits in obigen Rechnungen vertan haben, schätze mal das wir uns einig sind das das "das Kraut nicht fett macht" ;) |
Re: Einmal mit DEC Ver- und Entschlschlüsseln funktioniert n
Zitat:
Das ist dann aber nur eine Seite der Medaillie. Denn wie oben schon gesagt schützt der Salt in Zusammenarbeit mit der sicheren Hashfunktion auch vor anderen Angriffen. In jedem Falle ist also ein solcher Salt sinnvoll weil er wenn er zufällig gewählt wurde beweisbar nicht die Sicherheit reduzieren kann, aber mit sehr sehr hoher Wahrscheinlichkeit immer die Sicherheit erhöht und viele effiziente Angriffe sogar unmöglich machen. Gruß Hagen |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:01 Uhr. |
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