Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Dateien verschlüsseln - aber wie? (https://www.delphipraxis.net/9486-dateien-verschluesseln-aber-wie.html)

daniel-volk 27. Sep 2003 14:23


Dateien verschlüsseln - aber wie?
 
Noch eine Frage:

Ich möchte eine verschlüsselungssoftware schreiben, die mit dem AES-Algorithmus arbeitet.
Kennt ihr da irgendwelche Tools, mit denen das einfach möglich ist?
Kurz gesagt: Ich suche einen Code (z.B. eine Unit), wo ich nur einen Eingabe- und Ausgabepfad sowie ein Passwort angeben muss und schon ver- / entschlüsselt das.
Kennt ihr sowas? Oder etwas Ähnliches, das aber einfach zu verwenden ist.

Und wenn zufällig jemand vernünftige Infos über Rijndael hat, dann bin ich darüber auch nicht böse. Schließlich will ich ja wenigstens wissen, wie AES funzt, wenn ich den Code schon nicht selbst schreibe! :zwinker:

THX,
McDV.

PS: Natürlich bin ich euch auch dankbar für Infos über andere Verschlüsselungen wie z.B. RSA.
Kann ich nämlich alles gut gebrauchen - wir haben das Thema Kryptographie im Moment in der Schule :coder: - oder besser gesagt im Info-Unterricht.

Luckie 27. Sep 2003 15:03

Re: Dateien verschlüsseln - aber wie?
 
Kuck mal dach dem DEC von Hagen Redmann. Da ist alles drin.

anku 27. Sep 2003 15:04

Re: Dateien verschlüsseln - aber wie?
 
geh mal auf http://www.cryptool.de/. Da findest du recht gesammelte Infos rund um kryptographie.

daniel-volk 27. Sep 2003 15:47

Re: Dateien verschlüsseln - aber wie?
 
Danke erst einmal für eure Antworten, aber ich komme mit den Infos immer noch nicht ganz zurecht:

Wie finde ich das DEC von Hagen Redmann (negaH)? Ich hab nach gesucht, aber nichts Passendes gefunden. :(

Und das CrypTool ist echt ein schönes Prog (verwende ich schon seit längerer Zeit), aber in der Hilfe steht auch nichts drin.
Eigentlich geht es mir ja darum, dass ich einerseits einen Code zur verwendung finde und andererseits eine Beschreibung des Algorithmus für AES und SHA (für Hashwerte).

MfG. :bounce2:

daniel-volk 27. Sep 2003 20:01

Re: Dateien verschlüsseln - aber wie?
 
Für SHA-1 Hash-Berechnung hab ich eine Unit gefunden. Geht auch erstaunlich gut.
Aber leider fehlt mir immer noch eine Unit für AES. Kann mir da noch jemand weiterhelfen?

THX!

negaH 27. Sep 2003 23:33

Re: Dateien verschlüsseln - aber wie?
 
Geh auf VCLComponents, Delphi Super Page, Torry, Delphi JEDI, usw. usw.
Wenn du nicht suchen willst dann kannste bei VCLComponents oder DSP über die Top 10 Freeware Komponenten gehen, da sollte das DEC, eg. Cipher, auf Platz 2 oder 3 sein.

Gruß Hagen

Luckie 27. Sep 2003 23:36

Re: Dateien verschlüsseln - aber wie?
 
Mach doch endlich mal eien kleine Page dafür. Oder gestatte es mir das Archiv in meine Ablage zu legen: http://www.luckie-online.de/files/exports/ . Da kann man dann einfach von hier drauf einen lIOnk angeben, wenn nötig.

DaFox 28. Sep 2003 01:22

Re: Dateien verschlüsseln - aber wie?
 
Hi!

Eine klitzekleine Page dafür gibt es ja schon: http://www.dinosgmbh.de/dec/index.htm
Aber wenn ich das richtig sehe, gibt es keine Downloads auf der Seite.

Ich würde die Idee mit Luckies Ablage begrüßen.

Gruß,
Markus

negaH 28. Sep 2003 12:12

Re: Dateien verschlüsseln - aber wie?
 
Ja dies stimmt. Es ist aber ineffizient auf diesem Wege eine Freeware zu verbreiten. Viel besser sind dann doch die einschlägigen WEB Seiten. Ich dachte auch nicht das diese Seiten in der Delphigemeinde so unbekannt sind :)

Gruß Hagen

Luckie 28. Sep 2003 12:36

Re: Dateien verschlüsseln - aber wie?
 
Unbekannt nicht, man findet es nur schlecht. Alsich auf Torry nach DEC gesucht habe, wurde ich nicht fündig. Erst eine manuelle Suche brachte den Erfolg.

negaH 28. Sep 2003 13:03

Re: Dateien verschlüsseln - aber wie?
 
Torry naja, nutze ich weniger.
Besser organisiert ist Delphi Super Page oder VCLComponents. Dort ist es ziemlich einfach und offensichtlich was zu finden. Beide enthalten eine Kategorie "Kryptographie und Komprimierungen". Dort wird man auch DEC finden. Übrigens es heist zwar "DEC" = "Delphi Encryption Compendium" aber viele veröffentlichen es einfach als Cipher.zip. Alternativ besteht bei beiden Seiten die Möglichkeit über die Top Ten Download Listen aller Delphi Komponenten zu gehen. Auch dort sollte man DEC ziemlich schnell finden.
Ich sehe also nicht unbedingt die Notwendigkeit jetzt eine rießige eigene WEB Page zu basteln.
1.) kostet es mich Zeit
2.) finde ich nur Sites gut deren Inhalt immer aktuell gehalten wird, und das kann ich momentan nicht
3.) ist DEC selber eine private Entwicklung in meinem Hobby, also noch nicht mal eine Freeware für andere extra entwickelt, sondern einfach mein privates Ding das ich anderen zur Verfügung stelle, mehr nicht.
4.) ist DEC kein Allheilmittel und Just in Time Package, um sich nicht mit Kryptographie beschäftigen zu müssen. Eher das Gegenteil, einer der es nutzen will muß unbedingt sich in Kryptographie auskennen, es dient dann nur als Zeitersparnis. Denn es enthält gute Implemetierung der bekannten Verfahren die auch getestet sind.
5.) eine Verallgemeinerung in der Kryptographie durch unüberlegtes und nicht Wissensbasierte Anwendung von DEC widerspricht der Kryptographie selber. D.h. DEC ist keine Garantie das durch dessen Benutzung auch sichere Systeme entstehen. Das Gegenteil ist der Fall. Einer der nicht weis was er tut wird mit DEC eher noch unsichere Systeme bauen, denn er meint durch DEC wäre es sicher obwohl seine falsche Anwendung vom DEC es erst recht unsicher macht.
Dies ist der Hauptgrund warum ich immer wehement versuche für DEC keine fertigen Lösungen zu veröffentlichen oder eben WEB Seiten darüber zu schreiben. Es kann nämlich keine vorgefertigten und maßgeschneiderten kryptographische Systeme geben.


Gruß Hagen

daniel-volk 28. Sep 2003 13:55

Re: Dateien verschlüsseln - aber wie?
 
So,

das DEC hab ich gefunden, aber ich kriege es nicht installiert.
Ich gehe wie üblich auf Komponente installieren und wähle die Datei DECReg.pas oder so.
Beim Kompilieren sucht er dann aber die Komponente DsgnInf.dcu ! Was ist das und wieso finde ich das nicht?

Kann mir da jemand helfen?

Danke!!! :firejump:

negaH 28. Sep 2003 14:04

Re: Dateien verschlüsseln - aber wie?
 
Weil du Delphi 6 oder 7 hast. Borland hat die benötigten Units einfach umbenannt von D3,D4,D5 zum D6,D7.

Unit DECReg.pas öffnen und dort in der Uses Klausel
"DsgnIntf" durch "DesignIntf, DesignEditors" ersetzen.

Unit DECUtil.pas in der initialization Sektion
InitTestIsOk := CRC32($29524828, GetTestVector, 32) = $9B497502;

Das wars, und DEC läuft auch in D6/D7.

Beide Änderungen sind nötig weil Borland Units umbenannt hat bzw. weil der integrierte Assembler geändert wurde.

Achso noch eines: die unit DECReg.pas MUSS unbedingt in ein DesignTime only Package eingebunden werden. Wird DECReg.pas als neue Komponente installiert so landet es meistens in das "Borland Benutzer Package", dies wäre ok.
Ansonsten bekommt man den allseits bekannten Fehler das Unit "Proxies.dcu" nicht neu kompiliert werden kann weil unit "Proxies.pas" nicht gefunden wurde. Auch dies ist eine Änderung die Bolrand zu verantworten hat.

Gruß Hagen

PS: die im WEB veröffentlichen DEC Sourcen wurden noch entwickelt als es kein Delphi 6 oder 7 gab.
Abgesehen davon sind also DEC's Sourcen absolut kompatibel programmiert wurden.

daniel-volk 28. Sep 2003 16:15

Re: Dateien verschlüsseln - aber wie?
 
OK, ich denke ich hab das jetzt geschafft. Die Verwendung des HashManagers ist ja auch recht einfach. Ich denke ich muss auch beim Verschlüsseln immer den Key an den Hashmanager weiterleiten, richtig?
Aber wie wähle ich dann den Verschlüsselungsalgorithmus? Ich kann einfach keinen außer Blowfish wählen!?

Ansonsten würde ich mich freuen, wenn jemand von euch mir noch eine kleine Einleitung in die Verwendung der Komponenten geben könnte.

Thx! :bounce2:

negaH 28. Sep 2003 17:33

Re: Dateien verschlüsseln - aber wie?
 
Als ersten Tipp von mir: "verzichte auf ThashManager und TCipherManager", beide sind eigentlich nur im DEC damit es überhaupt sichtbare Komponenten für die "Drag&Design" Programmierer gibt. Viel einfacher ist die direkte Anwendung der DEC Klassen.

Delphi-Quellcode:
function HashFromPassword(const Password: String): String;
begin
  Result := THash_SHA1.CalcString(Password, fmtMIME64);
end;
Erzeugt einen SHA1 Digest von Password und konvertiert diesen binären Digest sofort in das Internt MIME Base 64 Format, damit es "lesbar" wird.

Delphi-Quellcode:
function EncryptString(const Value, Password): String;
begin
  with TCipher_Blowfish.Create(Password, nil) do
  try
    Result := EncodeString(Value, fmtMIME64);
  finally
    Free;
  end;
end;
Verschlüsselt den String in Value mit Blowfish/Password. Das Resulat ist der verschlüsselte Wert der sofort wieder in das lesbare MIME64 Format konvertiert wird. Wichtig dabei ist es zu berücksichtigen das das Passwort im Blowfish nicht direkt benutzt wird. Es wird intern in ein Sessionkey umgewandelt Dazu wird mit einer Hash-Funktion Password in den Sessionkey umgewandelt.

Gruß Hagen

daniel-volk 29. Sep 2003 15:10

Re: Dateien verschlüsseln - aber wie?
 
OK, danke. Ich teste das mal.

daniel-volk 29. Sep 2003 15:49

Re: Dateien verschlüsseln - aber wie?
 
Sorry, aber ich bin (glaub ich) echt zu doof.
Ich selbst hab auch lieber so graphische Komponenten, weil ich dann wesentlich einfacher auf alle Funktionen zugreifen kann.
Eine einfache Verschlüsselung mit einem einfachen Kennwort hab ich auch geschafft,
Delphi-Quellcode:
CipherManager1.InitKey(Edit1.Text,0);
  Memo2.Text := CipherManager1.EncodeString(Memo1.Text);
aber das ist ja nun nicht Sinn der Sache, dass ich nur mit einem Algorithmus arbeite. Wie ändere ich das so, dass ich mit Rijndael verschlüsseln kann? Und was muss ich z.B. machen, damit alles im MIME64 Format ausgegeben wird?
Dabei möchte ich aber gerne die graphische Benutzung beibehalten, da ich mit reinem Code zu wenig Erfahrung habe.

Oder kennt jemand vielleicht ein Tutorial für die Verwendung des DEC? Das wäre super!

THX,
Daniel. :bounce1:

negaH 29. Sep 2003 17:09

Re: Dateien verschlüsseln - aber wie?
 
Hi Daniel,

Willst du DEC echt sicher verwenden musst du auch mit Objecten umgehen und programmieren können.
Du bist also nicht zu doof sondern lässt dir von mir nichts sagen. Verwende NICHT diese Komponenten, sondern erlerne wie man die DEC Klassen direkt benutzen kann. Nichts anderes machen diese Komponenten, nur mit dem Unterschied das sie viel zu unfelxibel und auch unsicher sind.

Erstmal: es ist KEIN Sicherheitsrisiko sich von vornherein nur auf einen Cipher und einen Hash Algorithmus zu beschränken. Im Gegenteil, es ist sogar eine zusätzliche Sicherheit und es kann dir im besten Falle 400Kbyte an Code in deiner EXE einsparen. Bedenke, im DEC sind 40 Cipher und 25 Hash Algorithmen implementiert. ALLE diese Klassen werden in die EXE eingelinkt wenn mit den Manager-Komponenten gearbeitet wird !
Das einzigst WICHTIGE ist das wenn der von dir ausgewählte Algorithmus in Zukunft gebrochen wird, und somit unsicher wird, das dein Code mit minimalsten Änderungen auf einen anderen und sicheren Algorithmus ausweichen kann. Dazu ist DEC prädistiniert.

Nun, du willst kurze Strings verschlüsseln und dazu Hashbasierte Passwörter benutzen. Dabei willst du sicherstellen das du später sehr schnell den Algo. wechseln kannst.

Delphi-Quellcode:
const
  DefCipherClass: TCipherClass = TCipher_Blowfish;
  DefHashClass: THashClass = THash_SHA1;
  DefStringFormat: Integer = fmtMIME64;

function RandomString(Len: Integer): String;
// erzeugt Zufallsstring
begin
  SetLength(Result, Len);
  RndSeedBuffer(Result[1], Len);
end;
 
function Encode(const Value, Password: String): String; overload;
// verschlüsselt String in Value mit Password
// dabei wird der PlainText zusätzlich mit Zufallsdaten am Anfang expandiert
// um bestimmte Angriffe zu verhindern
var
  Data: String;
begin
  with DefCipherClass.Create('', nil) do
  try
    Mode := cmCFB;
    HashClass := DefHashClass;
    InitKey(Password, nil);
    Data := RandomString(BufSize) + Value;
    Result := EncodeString(Data, DefStringFormat);
  finally
    Free;
    ProtectString(Data); // Speicher von Data wird überschrieben
  end;
end;

function Decode(const Value, Password: String): String; overload;
begin
  with DefCipherClass.Create('', nil) do
  try
    Mode := cmCFB;
    HashClass := DefHashClass;
    InitKey(Password, nil);
    Result := DecodeString(Value, DefStringFormat);
    Delete(Result, 1, BufSize); // lösche BufSize Bytes Zufallsstring
  finally
    Free;
  end;
end;

begin
// nun alle in der EXE möglichen Algos. registrieren, falls man mehrere dynamisch benutzen will
  RegisterDECClasses([TCipher_Blowfish, TCipher_IDEA, THash_MD5, THash_SHA1]);
// nun unsere globalen Klassentypen setzen
  DefCipherClass := DECClassByName('Blowfish', TCipher) as TCipher;
  DefHashClass := DECClassByName('MD5', THash) as THash;
// oder eben
  DefCipherClass := DECClassByName('IDEA', TCipher) as TCipher;
  DefHashClass := DECClassByName('SHA1', THash) as THash;
// oder hardcoded
  DefCipherClass := TCipher_Rijndael;
  DefHashClass := THash_RipeMD256;
end;
Wie du oben siehst geht alles sehr einfach ohne die Manager Komponenten, und wenn die Unit DECClasses.pas NICHT verwendet wird, würden im obigen Beispiel auch nur die Algorithmen Blowfish,IDEA,Rijndael,MD5,SHA1 und RipeMD256 in die EXE eingelinkt.

Noch einiges zu den Funktionen "Encode" und "Decode".
1.) sie erzeugen die nötigen Hashobjectes und Cipherobjecte selber, initialisieren sie mit dem Passwort, verschlüsseln die Daten und zerstören sofort dabach diese Objecte. D.h. deren Lebenszeit ist die kürzt mögliche Lebenszeit überhaupt. Die Managerkomponenten arbeiten im Gegensatz dazu, und würdem somit Spyprogrammen die die Speicherbereiche deiner Anwendungen ausspionieren viel Freiraum geben um das Passwort des Benutzer's zu finden.
JEDE Komponentenbasierte Verschlüsselung hat das Problem das deren Lebenszeit viel zu lange dauert. Somit kann man während dieser Lebenszeit mit einer Spysoftware deren Speicherbereiche analysieren um somit an das Passwort zu kommen. Grundsätzlich sollte die Lebenszeit kryptographischer Objecte also so kurz wie möglich gehalten werden. Dies geht aber nur wenn man diese Objecte erst wenn man sie benötigt erzeugt, dann benutzt und sofort wieder zerstört.
2.) ich benutze den CipherMode cmCFB. Dieser ist zwar lansgammer als andere Ciphermodes, dafür ist er aber ein vielfaches sicherer mit sehr kurzen Nachrichten.
3.) die eigentliche Nachricht wird am Anfang mit Zufallsbytes vergrößert. D.h. Encode() verschlüsselt als erstes mal paar Bytes Zufallsdaten und erst dann die eigentliche Nachricht. Dies ist enorm wichtig damit man z.B. keine "known Cipher Text" Attacks machen kann.


Gruß Hagen

daniel-volk 30. Sep 2003 16:17

Re: Dateien verschlüsseln - aber wie?
 
OK,

ich will mal auf die hören und es codegesteuert machen.
Dann muss ich doch in die Project-uses
Delphi-Quellcode:
Cippher in '..\Source\Cipher.pas',
DECUtil in '..\Source\DECUtil.pas',
Hash in '..\Source\Hash.pas'
einfügen.
Zudem bekommt jede Unit noch die uses:
Delphi-Quellcode:
DECUtil, Cipher, Hash
In deinem Demo hab ich mir die String-Verschlüsselung angeguckt. Das ist ja alles sehr plausibel, aber wie wähle ich bitte die Algorithmen für Hash und Cipher?
Ich krieg das einfach nicht hin. Ganz egal, ob ich nun mit dem Cipher-Manager oder ohne ihn arbeite.

:wiejetzt:

Für Tipps wäre ich sehr dankbar.

An Alle, die schon einmal das DEC verwendet haben:
Ich weiß ja nicht wie ihr das macht, aber immer dann, wenn ich mit neuen Komponenten arbeite, baue ich mir ein ganz simples Prog, das die wichtigsten Funktionen der Komponente nutzt. Das lege ich mir dann zum späteren Nachschlagen auf der Festplatte ab.
Falls jemand sowas hat, das zudem nicht nur aus Projekt-Quellcode sondern hauptsächlich aus einer Unit besteht, wäre ich ihm/ihr sehr dankbar, wenn ich mir dieses einmal ansehen dürfte. Ich denke ich könnte darin vielleicht noch gezielter die Funktionen nachlesen.

Es geht nicht darum, dass ich überhaupt was verschlüsseln will (Strings und Dateien zu verschlüsseln ist kein Problem), sondern darum, dass ich nicht weiß, wie ich den Algorithmus auf Rijndael ändern kann, den Hashmode auf MD256 (was nutzt man hier eigentlich üblicherweise mit Rijndael?) und wie ich die Ausgabe auf MIME64 stelle (nur beim Ver- / Entschlüsseln von Strings).

Danke im Voraus,
Daniel.

negaH 30. Sep 2003 17:38

Re: Dateien verschlüsseln - aber wie?
 
Hi Daniel,

In den vorherigen Postings habe ich eigentlich schon alles gezeigt was du benötigst. Angefangen damit wie man bei einer Verschlüsselung den Hash Algortihmus oder den Ciphermode einstellen kann, über die Verwendung dynamischer Klassen und deren Registration im DEC System um sie später per Name wieder zu lesen und zu benutzen. Dieser Thread zeigt sehr schön warum ich meine das ein Tutorial oder explizietere Dokumentation wenig hilfreich für die Anwender vom DEC ist. Man würde dadurch nur wie ein Pappagei diese Tutorials nachempfinden ohne sich jemals intensiv und tiefgreifender mit der Kryptographie und ihrer Anwendung beschäftigt zu haben.

Ok, trotzdem werde ich mal hier vesuchen dich tiefer einzuarbeiten.

Zitat:

Es geht nicht darum, dass ich überhaupt was verschlüsseln will (Strings und Dateien zu verschlüsseln ist kein Problem), sondern darum, dass ich nicht weiß, wie ich den Algorithmus auf Rijndael ändern kann, den Hashmode auf MD256 (was nutzt man hier eigentlich üblicherweise mit Rijndael?)
Geschmackssache:
SHA1 ist der am weitesten annerkannte Algorithmus und wird als sicher eingestuft.
MD4,MD5 sind sehr schnell aber in MD5 hat man kleinere Schwächen endteckt. Somit würde ich MD4/MD5 empfehlen um Indexe/Prüfsummen o.ä. aufzubauen, aber nicht um sicherheitsrelevante Passwörter o.ä. zu schützen.
RipeMD empfinde ich prsönlich als die beste Wahl, er ist sicher und analysiert wurden. Er ist in Europa ein Standardverfahren und für mich persönlich ist es wichtig das er eben NICHT amerikanisch ist. SHA1 z.B. wurde vom NIST und NSA abgesegnet.
Haval habe ich schon in einigen Anwendungen gesehen, er wird also benutzt und ist sicher. Der Vorteil von Haval ist das dessen Digestlänge sehr variabel ist. Das gleiche gilt für RipeMD.
Tiger ist ein sehr guter 64Bit Hash, also z.B. auf Itaniums sehr schnell. Allerdings ist er wie die nachfolgenden Hash's wenig bis garnicht analysiert. Denoch sind es Hash Algortihmen die durch Profis entwickelt wurden.
Square und Sapphiere sind Hash-Algos die auf Grund deren Entwicklungen ihrer gleichnamigen Verschlüsselungsalgos. entstanden sind. Da ich immer die Meinung vertrete das ein Hash Algo NICHT ein Cipher bzw. ein Cipher NICHT ein Hash sein sollte, würde ich diese nicht anwenden. Denoch gelten die Cipher Square/Sapphiere als gute Cipher und somit sind deren Hash-Pendants ebenfalls gut. Auf Sapphiere liegen Patente.
Snefru ist ein Ausnahme-Hash. Sollten irgendwan einmal ganz bestimmte Mathematischen Grundlagen gebrochen werden so würde ein ganze Latte von Hash/Cipher Algortihmen unsicher werden. In Punkto Hash wären das alle oben genannten, bis auf SHA1 und Snefru. Denn beide Verfahren haben wesentliche Unterschiede zu den anderen Verfahren.

Im Bereich der Cipher wird eine gute Analyse schwieriger für mich, da 1. im DEC 40 verschiedene Cipher sind und 2. diese sich untereinander stark unterscheiden.
Nungut, aös erste DES und seine Derivate 2DES, 3DES usw. DES ist ein Standard und will man auf andere Sorftwaredaten zugreifen die diesen Standard benutzen so muß man DES verwenden. Allerdings DES ist enorm alt (was ihn nicht unsicher sondern sicherer macht da er bis heute nicht offiziell gebrochen wurde) und deshalb würde ich ihn in neuen Projekten niemals verwenden. Besonders Single DES ist als unsicher einzustufen da dessen Schlüsslelänge nur 56 Bit beträgt.

Rijndael, Twofish, Blowfish und IDEA wären die Favoriten. Wobei Rijndael natürlich der AES Gewinner ist. Ob die politisch gesehen Gut oder Schlecht ist darüber lässt sich streiten. Man muß bedenken das das NIST unter Absegnung vom NSA Rijndael hauptsächlich ausgewählt hat weil das Verfahren über ein breite Palette von verschiedner Hardware scallierbar ist. Dies bedeutet z.B. das Rijndael auch enorm leicht in FPGA Hardware umzusetzen ist, diese FPGA aber genau das Instrument der mächtigen Organisationen sein wird um Brute Force Angriffe auf Rijndael Schlüssel durchzuführen.
IDEA gilt als Ausnahmecipher und als sicher ist aber duch Patente blockiert.
Twofish ist die Weiterentwicklung von Blowfish und beide wurden von Bruce Schneier entwickelt. Es fragt sich warum Schneier Blowfish weiterentwickeln musste zum Twofish. Beide sind sicher. Blowfish ist frei verwendbar.
TEA,RC4 und SCOP sind Streamcipher. Dadurch haben sie besondere Eigenschaften. RC4 ist ein anerkanntes Verfahren wogegen SCOP/TEA eher Undergrund Cipher sind. Beide wurden nicht expensiv analysiert. Denoch benutze ich gerade SCOP um enorm schnell große Datenmengen zu verschlüsseln, da SCOP eben eine der schnellsten Verschlüsselungen auf PC's ist. Natürlich muß man dann Abstriche in der Sicherheit machen.

Nicht unerwähnt soll bleiben das ich im DEC auch eine Eigenentwicklung eingebaut habe. Sie heist PMC=Polymoph Cipher. Bei diesem Verfahren gibt es keinen festen Verschlüsselungsalgorithmus mehr, sondern das Passwort und die Messages bestimmen wir der Cipher intern verschlüsselt. D.h. der PMC ist ein Verfahren das abhängig vom Passwort und der Messages erst zur Verschlüsselungszeit den Verschlüsselungsalgorithmus compiliert. Der PMC kann nicht auf FPGA Hardware implementiert werden, da er z.B. bei der Verschlüsselung von 1Kb Daten temporär ca. 10Mb an Verschlüsselungscode erzeugt.

Zitat:

und wie ich die Ausgabe auf MIME64 stelle (nur beim Ver- / Entschlüsseln von Strings).
Auch dieses habe ich in den vorherigen Postings gezeigt. Der letzte Parameter von TCipher.Encode-/DecodeString() gibt das Format an. Ich habe auf deine Wünsche hin mit fmtMIME64 gearbeitetm was exakt dem MIME Base 64 Verfahren entspricht. Um diese Sache dynamisch zu machen wurde eine Globale Variable DefStringFormat: Integer = fmtmIME64 benutzt.


Willst du in deiner Awendung nun z.B. mit Blwofish,SCOP,Rijndael,MD4,SHA1,RipeMD arbeiten so müssen die Unit Hash,Cipher,DECUtils eingebunden werden. DEC enthält nun alles ws nötig ist um mit dynamischen Klassen zu arbeiten, also so ähnlich wie die VCL es tut mit RegisterClass() und getClass().

Zur Intialisierungsphase der Anwendung müssen also dem DEC alle verwendbaren Algos. mitgeteilt werden.


Delphi-Quellcode:
uses Hash,Cipher,DECUtils;

initialization
  RegisterDECClasses([TCipher_Blowfish, TCipher_SCOP, TCipher_Rijndael, THash_MD4, THash_SHA1, THash_RipeMD128, .....]);
end.
Nun findest du in DECUtils.pas alle wichtigen Funktionen um auf diese registrierten Klassen zuzugreifen. Zb.

Delphi-Quellcode:
var
  Cipher: TCipherClass;
  Hash: THashClass;
begin
  Cipher := DECClassByName('SCOP', TCipher) as TCipher;
  with Cipher.Create() do ......

// oder
  Hash := DECClassByName('MD4', THash) as THash;
  Hash.CalcString('Test', nil, fmtMIME64);
end;
Das heist alle registrierten Klassen können durch ihren Klassennamen, z.B. "THash_MD4" oder deren Kurzname = "MD5", also dem Namen nach dem Unterstrich "_" über DECClassByName gefunden werden.

Zusätzlich zu dieser Methode implementiert DEC noch eine sogenante Identity. Dies ist ein 32 Bit Wert der eindeutig einen Algortihmus beschreibt. Würde man z.B. mit solchen durch den User auswählbaren Algos. arbeiten und eine Datei verschlüsseln, muß das Programm ja wissen welches Verfahren benutzt wurde. Nun dazu speichert man einfach Cipher.Identity in den Header der Datei. Mit

Delphi-Quellcode:
var
  Cipher: TCipherClass;
  Hash: THashClass;
  CipherIdentity: Cardinal;
  HashIdentity: Cardinal;
begin
// lade header aus verschlüsseltem Stream
  Stream.Read(CipherIdentity, SizeOf(CipherIdentity));
  Stream.Read(HashIdentity, SizeOf(HashIdentity));
  Cipher := DECClassByIdentiy(CipherIdentity, TCipher) as TCipher;
  Hash := DECClassByIdentity(HashIdentity, THash) as THash;
 
  with Cipher.Create('', nil) do
  try
    Mode := cmCTS;
    HashClass := Hash;   // <--- ändere hier den Password-Hash-Algo.
    InitKey(Password, nil);
    DecodeStream(Stream, Dest, Stream.Size - Stream.Position);
  finally
    Free;
  end;
   
end;
wird dies demonstriert. Dies Identites können sehr einfach für jede Anwendung separat angepasst werden, sprich serialisiert werden. Einfach IdentityBase in DECUtils.pas ändern.

Oben wurde auch gezeigt wie du den Hash-Algortihmus der das Password in den Sessionkey umwandelt geändert werden kann. Dieses Verhalten habe ich auch schon in den letzten Posting gezeigt.

Schau dir bitte die DECUtils.pas genauer an, dort findest du neben DECRegisterClasses() usw. andere wichtige Funktionen.

Gruß Hagen

daniel-volk 30. Sep 2003 20:30

Re: Dateien verschlüsseln - aber wie?
 
Danke!!! :bounce1: :bounce2:

Das hat mir glaub ich sehr geholfen (und sicherlich auch einigen Anderen).
Das größte Problem war wohl, dass ich keine initialization geschrieben hatte. :oops:

Na ja, jetzt wird's schon gehn.

MfG,
Daniel. :coder:

daniel-volk 1. Okt 2003 20:26

Re: Dateien verschlüsseln - aber wie?
 
Hi,

komme inzwischen ganz gut klar. :mrgreen:
Hab mir die für mich wichtigen Aspekte aus deinen Posts angesehen und die Units durchgearbeitet.

Anfangs bin ich nur daran verzweifelt, dass ich Rijndael einfach nicht definieren konnte und auch nicht in der Unit fand - bis ich dann feststellte, dass es neben Cipher auch noch Cipher1 gibt!!!

So weit so gut, es gibt ja die Aktionen paEncode (zum Verschlüsseln), paDecode (entschlüsseln) und dann noch paWipe. Über die Funktion des Letzten bin ich mir nicht im Klaren. Wiped das die Quelldatei oder was?

Gibt es eigentlich eine Funktion zum Wipen von Dateien, sodass ich die Option "Quelldatei nach Verschlüsseln wipen" einbauen kann?

Und: Der CipherManager verfügt über ein OnProgress Event. Wie kann ich darauf zugreifen, wenn ich den Manager nicht verwende (was bei mir der Fall ist)?

Danke,
Daniel. :bounce2:

Luckie 2. Okt 2003 04:32

Re: Dateien verschlüsseln - aber wie?
 
Eine Frage noch: Das Passwort wird im Header logischerweise nur als Hash-Wert gespeichert oder?

Also:
Code:
////////////////////////////////
Header
  CipherIdentity: Cardinal
  HashIdentity: Cardinal
  PW als Hash: String;
////////////////////////////////
Daten
  verschlüsselte Datei
  ...
  ...
  ...
  ...
  ...
  ...
  ...
////////////////////////////////
Den Header darf man natürlich nicht mit verschlüsseln, also erst die Datei verschlüsseln und dann den Header dazupacken. Beim Entschlüsseln Header auslesen, Passwort überprüfen, Header aus der verschlüsselten Datei entfernen, entschlüsseln.

Hm. :gruebel:

Der Passwort Hash wird ja ein String. Wie schreibt man denn ein Header-Record mit eienm Delphi HugeString, also mit einem String dessen Länge man nicht kennt? Somit ist ja auch die Headergröße nicht bekannt. Oder kann man davon ausgehen, dass ein Hash nicht länger wird als 255 Zeichen?

PS. Ich denke nur mal laut. :wink:

negaH 2. Okt 2003 08:45

Re: Dateien verschlüsseln - aber wie?
 
Zitat:

So weit so gut, es gibt ja die Aktionen paEncode (zum Verschlüsseln), paDecode (entschlüsseln) und dann noch paWipe. Über die Funktion des Letzten bin ich mir nicht im Klaren. Wiped das die Quelldatei oder was?
Jetzt dringen wir tiefer in die DEC Klassen ein, und man erkennt viele Sünden die ich heute nicht mehr so designen würde. TCipher/THash und TRandom sind alle von der gleichen Klasse TProtection abgeleitet. Jede Klasse wie TCipher/THash/TRandom implementieren ihre EIGENEN Methoden die natürlich Algorithmen spezifisch sind. D.h. ein TCipher hat die Methoden .En-/DecodeBuffer, .En-/DecodeString() usw. zum Ver- und Entschlüsseln. Ein THash wiederum seine .CalcXYZ usw Methoden. Diese Methoden unterstützen KEINE ProgressCallback.

Aber in TProtection gibt es ebenfalls ähnliche Methoden, die für ALLE von TProtection abgeleiteten Klassen gültig sind, Zb. TProtection .CodeStream(). Man kann also mit einem Cipher/Hash/Random ebenfalls über diese Methoden von TProtection Daten verschlüsseln. Kryptographisch gesehen würde ich aus heutiger Sicht meine damaligen Absichten als naiv bezeichnen, und nicht mehr auf die TProtection Methoden zurückgreifen. Man kann zwar tatsächlich auch mit einer Hash-Funktion eine Verschlüsselung machen, man nennt diese offiziell MDC=Message Digest Cipher, heutzutage würde ich aber grundsätzliche solche Verfahren ablehnen. Nungut, DEC enthält sie und somit muß ich auch darauf eingehen. Nur die Methoden von TProtection enthalten die Möglichkeit eine Progress-Callback zu benutzen. Hier im Forum findest du in der Codelibrary einen TProgressStreamAdapter der diese Progressfunktionalität viel eleganter lösst. Die im DEC enthaltene Callback ist global und nicht threadsafe und funktioniert nur mit den TProtection.CodeXXXX Methoden. Also wiederum einige Nachteile. Um denoch einen Progress zu coden schauste mal in DECUtil.pas rein, dort findest du eine globale Variable "Progress: TProgressEvent". Diese musst du vor der Benutzung von TProtection.CodeXXXX() auf eine eigene Eventmethode setzen und danach wieder auf nil. Genauso gehen auch die Manager Components vor.

Zitat:

Gibt es eigentlich eine Funktion zum Wipen von Dateien, sodass ich die Option "Quelldatei nach Verschlüsseln wipen" einbauen kann?
Jo, eben paWipe :) Du erzeugt einen TCipher oder TRandom und benutzt dann die Methoden von TProtection mit der Action paWipe statt paEncode.

Zitat:

Und: Der CipherManager verfügt über ein OnProgress Event. Wie kann ich darauf zugreifen, wenn ich den Manager nicht verwende (was bei mir der Fall ist)?
Ähm, oben schon beantwortet.

@Luckie:
Zitat:

Eine Frage noch: Das Passwort wird im Header logischerweise nur als Hash-Wert gespeichert oder?
Es sollte überhaupt nicht mehr gespeichert werden, egal in welcher Form. Ansonsten sind bei bekannter Hashtransformation des Passwortes immer Wörterbuch-Angriffe möglich die mit schlecht gewähltem Passwort sehr efizient sein können.

Also wichtigste Regel: Ein Passwort ist ein Geheimnis das meistens durch den Menschen sehr schlecht und weit unter den Sicherheitsanforderungen ausgewählt wurde. Deshalb gehört dieses Passwort NUR in's Hirn und sollte in keinerlei Form gespeichert werden. Es sei denn, es würde mit einem viel besseren Passwort verschlüsselt oder transformiert.

Zitat:

Den Header darf man natürlich nicht mit verschlüsseln, also erst die Datei verschlüsseln und dann den Header dazupacken. Beim Entschlüsseln Header auslesen, Passwort überprüfen, Header aus der verschlüsselten Datei entfernen, entschlüsseln.
Dies ist korrekt. In meinem obigen Postings wurde das berücksichtigt. JEDE Funktion die mit Stream's arbeitet, sollte immer ausgehend von der aktuellen Stream.Position mit dem Stream arbeiten. So zumindestens arbeitet die VCL und auch DEC. Werden also aus einem Stream 8 Bytes gelesen und erst danach mit Cipher.DecodeStream() gearbeitet, so beginnt der Cipher mit dem 9'ten Byte im Stream zu entschlüsseln. Einzigste Aussnahme beim DEC ist wenn man z.b. Cipher.DecodeStream(Source, Dest, -1); sprich Size = -1 aufruft. Dann wird intern Stream.Position := 0; gesetzt.
Auch solche "Ausnahmen" würde ich heutzutage NICHT mehr so programmieren.

Zitat:

Der Passwort Hash wird ja ein String. Wie schreibt man denn ein Header-Record mit eienm Delphi HugeString, also mit einem String dessen Länge man nicht kennt? Somit ist ja auch die Headergröße nicht bekannt. Oder kann man davon ausgehen, dass ein Hash nicht länger wird als 255 Zeichen?
Ein Hash erzeugt immer einen binären Digest fester Länge. Z.b. SHA1 eben 20 Bytes. Wird dieser Hash konvertiert, durch TStringFormat_xxxx Klassen, dann werden zwar diese 20 Bytes expandiert, aber trotzdem hat der String dann mit dem gleichen Hash immernoch feste Länge.

Ein Header mit variabler Größe sollte nach dem Ident zur Erkennung des Headers eine Größenangabe in Bytes enthalten. Der Ident und die Größenangabe haben dann feste Länge und können nun direkt ausgelesen werden. Somit besteht ein Header variabler Größe im Grunde genommen aus ZWEI Teilen. Einen festen Part am Anfang aus Ident + Größenangabe und einem variablen Teil gleich danach der exakt Header.Size Bytes groß ist.
Generell bevorzuge ich aber Header die immer feste Länge haben, meistens 16,32,48 Bytes. Der Rest der fehlenden Bytes um auf diese Größen zu kommen wird einfach reserviert. Damit sind dann auch Erweiterungen des Headers möglich.

Auf eine Verschlüsselung des Headers sollte verzichtet werden, da sonst "known plaintext attacks" möglich sind. Gleich nach dem Header sollte man die Daten verschlüsselt speichern. ABER, diese Daten sollten mit Cipher.BufSize Bytes Zufallsdaten am Anfang erweitert werden.

Gruß Hagen

Luckie 2. Okt 2003 08:53

Re: Dateien verschlüsseln - aber wie?
 
Mann, ich sollte ins Bett gehen, das Passwort speichern war natürlich Quatsch mit Soße. :roll: Und damit hat sich auch das Header-Problem gelöst.

Aber was man speichern könnte, wäre ein Hash von der original Datei, um nach dem Entschlüsseln überprüfen zu können, ob sie noch in Ordnung ist.

Was machen eigentlich deine Streams, wenn man mit dem falschen Passwort entschlüsselt?

negaH 2. Okt 2003 09:20

Re: Dateien verschlüsseln - aber wie?
 
Zitat:

Aber was man speichern könnte, wäre ein Hash von der original Datei, um nach dem Entschlüsseln überprüfen zu können, ob sie noch in Ordnung ist.

Was machen eigentlich deine Streams, wenn man mit dem falschen Passwort entschlüsselt?
Sie werden falsch entschlüsselt und produzieren Datenmüll.
Somit ist es eine gute Idee eine Prüfsumme zu berechnen. Dazu benötigt man aber nicht unbedingt eine separate Hashfunktion, sondern man kann im Ciphermode cmCTS einfach nach dem verschlüsseln der Daten mit Cipher.CalcMAC eine Prüfsumme erzeugen. Die Ciphermodes cmCBC,cmCTS ua. sind Modis die per Feedback Register blockweise die Daten zerlegen und jeden Block separat verschlüsseln. Dabei wird aber über das Feedback Register jeder Block mit dem nachfolgenden Block verknüpft. Somit würde sich ein Bitfehler eines Datenblockes in den nächsten Datenblock fortpflanzen. Nun im cmCBC Modus beträfe so ein Fehler nur den nachfolgenden Block und somit ist cmCBC ungeeignet als C-MAC = Cipher-Message Authentification Code. cmCBC nennt man auch einen "Selbst synchronisierenden Modus", da er eben bei einem Bitfehler nur ZWEI Datenblöcke falsch entschlüsselt, alle nachfolgenden Blöcke sind dan wieder ok. Den cmCTS Mode habe ich aber so konstruiert das ein einzigster Bitfehler am Anfang der Message ALLE nachfolgenden Bits beeinflusst. D.h. der Fehler beeinflusst die ganze Nachricht bis zum Ende und somit auch den letzten Block der Nachricht. Wird damit ein C-MAC berechnet und dieser in die Datei gespeichert, kann bei der Entschlüsselung der neue C-MAC mit dem gespeicherten verglichen werden. Sollten sie ungleich sein, so wurde entweder ein falsches Paswort benutzt oder die Daten wurden manipuliert. Allerdings, dieser Modus ist ein "Alles oder Nichts" Modus.

Alternativ könnte man aber den von mir vorgeschlagenen Zufallsdatenblock dazu benutzten um zu erkennen ob das richtige Passwort eingegeben wurde. Der Dateiaufbau sähe dann so aus: Header + Zufallsdaten + Prüfsumme über Zufallsdaten + Message. Bis auf den Header werden alle Teile wie eine einzigste Nachricht verschlüsselt. Bei Entschlüsseln kann man sofort nach Entschlüsselung der Zufallsdaten + Prüfsumme diese erstmal abtesten. Sollte sie falsch sein ist mit hoher Wahrscheinlichkeit das Passwort falsch.

Ein Angreifer der nun per Brute Force und einer Test-Entschlüsslung arbeitet müsste aber dann auch nur bis zur Prüfsumme entschlüsseln um zu sehen ob sein Testpasswort das richtige ist. Macht man es aber über die C-MAC Methode so muß der Angreifer und auch der Benutzer die Message immer vollständig entschlüsseln um zu erfahren ob alles korrekt ist.

Bei all diesen Überlegungen könnte man mich fragen: "warum hast du nicht gleich ein solches Datenformat und Datenprotokoll in DEC integriert ?", denn der zusätzlich nötige Aufwand um mit DEC korrekt und sicher Daten zu verwalten ist ja immernoch erheblich !

Nun, einfach weil es viel zu viele unterschiedliche Anforderungen und Standarddaten Formate gibt. Man kann es also im Grunde keinem richtig Recht machen. Deshalb ist dies die Aufgabe des Benutzers vom DEC.

Gruß Hagen

Luckie 2. Okt 2003 09:31

Re: Dateien verschlüsseln - aber wie?
 
Das war ja auch ein Punkt in der DLL von dem Russen, der hat das Passwort in der verschlüsselten Datei gespeichert.

Ich wollte erstmal den Header so einfach wie möglich halten. Das heißt nur die CipherIndetity speichern und eine Prüfsumme der original Datei.

Wie lange braucht es einen Hash/Prüfsumme von einer 100 MB Datei zu erstellen? Wie schnell sind die Hash Algorithmen im DEC? Und kann man da auch mit deinem ProgressAdapter arbeiten, also mit Streams? Wenn es länger dauert könnte man dann einen Fortschritt anzeigen. Dass das sowieso in Threads ausgelagert wird ist klar.

negaH 2. Okt 2003 10:42

Re: Dateien verschlüsseln - aber wie?
 
Zitat:

Wie lange braucht es einen Hash/Prüfsumme von einer 100 MB Datei zu erstellen?
Hängt davon ab mit welchem Algo. gearbeitet wird. Die DEMO im DEC enthält einen Performancevergleich alle Algos. Mit wenigen Handgriffen haste diese auf deine Testfälle umgeändert. Normalerweise sollte MD4 z.b. zwischen 40 - 340 Mb/sec schnell sein.

Zitat:

Wie schnell sind die Hash Algorithmen im DEC?
Relativ gesehen zu den anderen verfügbaren Algos. sind sie enorm schnell. Ich kenne nur zwei andere Implementationen die schneller sind. Einerseits behauptet Henrick Hellström in seinem StreamSec II das seine Implementationen zum Original DEC schneller sind, andererseits hat ein Russe Namens Anatoly Kaluzhinsky die Implementationen im DEC durch handmade Assembler Routinen verbessert. Dessen Algos. sind die schnellsten die ich kenne. Sie liegen bei mir aber auf "Halde" :) können aber von Tol's WEB Side downloaded werden, http://www.paco.net/~tol/hash/x86hotk.html

Zitat:

Und kann man da auch mit deinem ProgressAdapter arbeiten, also mit Streams? Wenn es länger dauert könnte man dann einen Fortschritt anzeigen. Dass das sowieso in Threads ausgelagert wird ist klar.
Aber natürlich immer. Man darf dann eben nur die DEC Methoden benutzen die auch mit Streams arbeiten. Zwischen dem Orginal-Dateistream und dem Stream auf dem die DEC Methoden arbeiten wird einfach der TStreamProgressAdapter zwischen geschaltet. Somit laufen alle Zugriffe der DEC Methoden direkt über den TStreamProgressAdapeter und dieser leitet sie weiter an den originalen Stream.
Diese Methodik kann mit JEDEM TStream basierten System benutzt werden, sogar zum Laden von DFM's, Indy Streams usw. usw.

Gruß Hagen

negaH 2. Okt 2003 10:48

Re: Dateien verschlüsseln - aber wie?
 
Zitat:

Ich wollte erstmal den Header so einfach wie möglich halten. Das heißt nur die CipherIndetity speichern und eine Prüfsumme der original Datei.
Vergiss nicht die Hash.Identity mitzuspeichern. Diese ist notwendig um den richtigen Hash-Algo, der für die Konvertierung des Passwortes in den Sessionkey benutzt wird, zu setzen. Mit Cipher.HashClass.Identity kannste darauf zugreifen. Die Methode Identity ist eine Klassenmethode kann also auch mit Klassen verwendet werden, eg. THash_MD4.Identity.

Ich empfehle dir dringendst mit der Expansion der Message per Zufallsbytes zu arbeiten. Dies erhöht nicht nur marginal die Sicherheit, sondern ist ein MUSS um es sicher zu machen.

Normalerweise benutzt man dazu die sogenanten Initialization Vectors = IV's. Diese werden mit Zufallsbytes gefüllt und diese Bytes müssen unverschlüsselt mit gespeichert werden damit man wieder entschlüsseln kann. Solche IV's stellen sicher das man bestimmte effektive Angriffe nicht mehr durchführen kann. Nun, ich persönlich finde diese IV's nicht so gut, da sie eben lesbar gespeichert werden. Besser ist es dann gleich diese IV-Zufallsbytes zur Expansion der Nachricht zu verwenden und sie am Anfang der Nachricht mit zu verschlüsseln. Dies hat die gleichen Auswirkungen wie ein IV, ist aber sicherer da sie verschlüsselt sind. IV's und diese Zufallsbytes Expandierung setzen voraus das mit einem Feedback-Ciphermode gearbeitet wird. D.h. cmECB darf dann nicht benutzt werden.
Diese IV's werden in DEC per default durch die Verschlüsselung von 0 Bytes mit dem Passwort initialisiert. Wenn sie also NICHT explizit benutzt werden, so ist der IV im DEC nichts anderes als die Verschlüsselung von 0 Bytes. Nur mit dem richtigen Passwort wäre also in der Entschlüssung der IV identisch mit dem IV zur Verschlüsselung. Dies hat aber den Nachteil das ein Angreifer der dies weis den IV dazu benutzen kann um nur mit einem Block Entschlüsslung und bekanntem Messageheader eine Brute Force Attacke auf das Passwort machen kann. Wird die Message mit Zufallsdaten expandiert funktioniert dies nicht mehr.

Gruß Hagen

daniel-volk 3. Okt 2003 00:12

Re: Dateien verschlüsseln - aber wie?
 
Hi,

ich bin's mal wieder:
Ich hab mein Prog jetzt so weit, dass es Texte verschlüsselt und in gewisser Weise auch Dateien.
Aber bei den Dateien stehe ich vor einem Problem:
Ich schaffe es einfach nicht den Hashwert der Originaldatei (ein 28-stelliger String) so zu speichern, dass ich ihn hinterher auch wieder lesen kann. Und vor dem Entschlüsseln der Datei muss ich den String ja sicherlich auch irgendwie wieder aus dem Header entfernen. :?: :!:

Mein Code sieht bis jetzt folgendermaßen aus:
Delphi-Quellcode:
const
  DefCipherClass: TCipherClass = TCipher_Rijndael; //mögliche siehe Cipher.pas und Cipher1.pas
  DefHashClass: THashClass = THash_SHA1; //mögliche siehe Hash.pas
  DefStringFormat: Integer = fmtMIME64; //mögliche siehe DECUtil.pas
  HashLength = 28; // Länge des Hash-Wertes als String geschrieben
  CipherMode = cmCTS; // Cipher-Mode: cmCTS, cmCBC, cmCFB, cmOFB, cmECB
  ErrorMessageText = 'Fehler: Es wurde entweder ein falsches Kennwort eingegeben oder der Ciphertext wurde manipuliert.'; // Nachricht, die bei falschem Passwort etc angezeigt wird
  ErrorMessageFile = 'Fehler: Es wurde entweder ein falsches Kennwort eingegeben oder die Quelldatei wurde manupuliert.';
  // Modi zur Definition der Dateioperationen
  mdNormal = 0;
  mdClear = 1;
  mdWipe = 2;
  // Modus: mdNormal: Quelldatei bleibt erhalten, Temp (selbst verschlüsselt) wird normal gelöscht
  //        mdClear: Quelldatei wird normal gelöscht, ansonsten s.o.
  //        mdWipe: Quell- und Tempdatei werden gewiped

  NoSourceMessage = 'Die Quelldatei konnte nicht gefunden werden';
  DestExistsMessage = 'Die Ausgabedatei existiert bereits. Soll Sie überschrieben werden?';
  DestExistsCaption = 'Ausgabedatei existiert bereits';
  ErrorMessage = 'Fehler: Eine der durchzuführenden Operationen konnte eventuell nicht ordnungsgemäß ausgeführt werden.';

implementation

{$R *.dfm}

function TFrmCipher.ReadHeader(Filename: string): string;
var
  Header: string;
  FileStream: TFileStream;
begin
  FileStream := TFileStream.Create(Filename, fmOpenRead);
  if not Assigned(FileStream) then
  begin
    RaiseLastOSError();
    exit;
  end;
  try
    FileStream.ReadBuffer(Header, Hashlength);
    result := Header;
  finally
    FreeAndNil(FileStream);
  end;
end;

function TFrmCipher.DecodeFile(Input, Output, Passwd : string; Modus : word):boolean;
// mdNormal = 0
// mdClear = 1
// mdWipe = 2
var
  DateiHash : string;
  OldHash : string;
begin
  If FileExists(Input)
  then begin
  // Abbruchkriterium, falls DestFile Existiert
  If FileExists(Output) then if Application.MessageBox(DestExistsMessage,DestExistsCaption,MB_YESNO)=7 then exit;
  // Original-Hash-Wert aus Dateiheader auslesen
  OldHash := ReadHeader(Input);
  // Datei verschlüsseln
  with DefCipherClass.Create('',nil)
  do begin
       try
         // Cipher einstellen
         Mode := CipherMode;
         HashClass := DefHashClass;
         InitKey(Passwd,nil);
         CodeFile(Input,Output,paDecode);
         // Hash-Wert der Originaldatei berechnen
         with DefHashClass.Create(nil)
         do begin
              try
                DateiHash := CalcFile(Output,nil,DefStringFormat);
              finally
                Free;
              end;
            end;
       finally
         Free;
       end;
    If OldHash <> DateiHash
    then begin
           ShowMessage(ErrorMessageFile);
           Exit;
         end;
    If FileExists(Output)
    then begin
           Case Modus of
           1 : DeleteFile(Input);
           2 : begin
                 with DefCipherClass.Create('',nil)
                 do begin
                      try
                        InitKey('',nil);
                        CodeFile(Input, Input, paWipe);
                        DeleteFile(Input);
                      finally
                        Free;
                      end;
                    end;
               end;
           end;
         end
         else ShowMessage(ErrorMessage);
     end;
    end
    else ShowMessage(NoSourceMessage);
    Result := FileExists(Output);
end;

function TFrmCipher.AddHeader(Header: string; Filename: String; Modus : integer): Boolean;
var
  SourceFile, DestFile: TFileStream;
const
  extension = '.tmp';
begin
  result := FALSE;
  SourceFile := TFileStream.Create(Filename, fmOpenRead);
  if not Assigned(SourceFile) then
  begin
    exit;
  end;
  try
    DestFile := TFileStream.Create(Filename+Extension, fmCreate);
    if not Assigned(DestFile) then
    begin
      exit;
    end;
    try
      { Header in die Zieldatei schreiben }
      DestFile.WriteBuffer(Header, sizeof(Header));
      { Quelldatei dahinter kopieren / anhängen }
      DestFile.CopyFrom(SourceFile, SourceFile.Size);
      result := TRUE;
    finally
      FreeAndNil(DestFile);
    end;
  finally
    FreeAndNil(SourceFile);
  end;
  // Löschen der temporären Datei
  Case Modus of
  0 or 1: DeleteFile(Filename);
  2:begin
      with DefCipherClass.Create('',nil)
      do begin
           try
             InitKey('',nil);
             CodeFile(Filename,Filename,paWipe);
             DeleteFile(Filename);
           finally
             Free;
           end;
         end;
    end;
  end;
  if not RenameFile(Filename+Extension, Filename) then
  begin
    result := FALSE;
  end;
end;

function TFrmCipher.EncodeFile(Input, Output, Passwd : string; Modus : word):boolean;
// mdNormal = 0
// mdClear = 1
// mdWipe = 2
var
  DateiHash : string;
begin
  If FileExists(Input)
  then begin
  // Abbruchkriterium, falls DestFile Existiert
  If FileExists(Output) then if Application.MessageBox(DestExistsMessage,DestExistsCaption,MB_YESNO)=7 then exit;
  // Datei verschlüsseln
  with DefCipherClass.Create('',nil)
  do begin
       try
         Mode := CipherMode;
         HashClass := DefHashClass;
         InitKey(Passwd,nil);
         CodeFile(Input,Output,paEncode);
         // Hash-Wert der Originaldatei berechnen
         with DefHashClass.Create(nil)
         do begin
              try
                DateiHash := CalcFile(Input,nil,DefStringFormat);
              finally
                Free;
              end;
            end;
         // Hash-Wert in Datei-Header schreiben
         AddHeader(DateiHash,Output,Modus);
       finally
         Free;
       end;
    If FileExists(Output)
    then begin
           Case Modus of
           1 : DeleteFile(Input);
           2 : begin
                 with DefCipherClass.Create('',nil)
                 do begin
                      try
                        InitKey('',nil);
                        CodeFile(Input, Input, paWipe);
                        DeleteFile(Input);
                      finally
                        Free;
                      end;
                    end;
               end;
           end;
         end
         else ShowMessage(ErrorMessage);
     end;
    end
    else ShowMessage(NoSourceMessage);
    Result := FileExists(Output);
end;

function TFrmCipher.EncodeText(Input, Passwd : string):string;
begin
  // Hash-Wert des Originaltextes hinzufügen (zur späteren Prüfung)
  with DefHashClass.Create(nil)
  do begin
      try
       Result := CalcString(Input,nil,DefStringFormat);
      finally
       Free;
      end;
  // Text verschlüsseln
  with DefCipherClass.Create('', nil)
  do begin
      try
       Mode := CipherMode; // auch möglich: cmCTS, cmCBC, cmCFB, cmOFB, cmECB
       HashClass := DefHashClass; // erforderlich
       InitKey(Passwd, nil);
       Result := Result + CodeString(Input,paEncode,DefStringFormat);
      finally
       Free;
      end;
     end;
    end;
end;

procedure TFrmCipher.Button1Click(Sender: TObject);// Text verschlüsseln
begin
  // Text verschlüsseln
  Screen.Cursor := crHourGlass;
  Memo2.Text := EncodeText(Memo1.Text,Edit1.Text);
  Screen.Cursor := crDefault;
end;

function TFrmCipher.DecodeText(Input, Passwd : string):string;
var HashStr1, HashStr2 : string;
begin
  // alten Hash-Wert auslesen
  HashStr1 := Copy(Input,1,HashLength);
  delete(Input,1,HashLength);
  //Text entschlüsseln
  with DefCipherClass.Create('', nil)
  do begin
      try
       Mode := CipherMode; // auch möglich: cmCTS, cmCBC, cmCFB, cmOFB, cmECB
       HashClass := DefHashClass; // erforderlich
       SetDefaultCipherClass(DefCipherClass); //nicht zwingend erforderlich, da normalerweise automatisch eingestellt
       InitKey(Passwd, nil);
       Result := CodeString(Input,paDecode,DefStringFormat);
      finally
       Free;
      end;
     end;
  // neuen Hash-Wert berechnen
  with DefHashClass.Create(nil)
  do begin
      try
       HashStr2 := CalcString(Result,nil,DefStringFormat);
      finally
       Free;
      end;
     end;
  // Hash-Werte vergleichen
  If HashStr1 <> HashStr2
  then ShowMessage(ErrorMessageText);
end;

procedure TFrmCipher.Button2Click(Sender: TObject);// Text entschlüsseln
begin
  // Text entschlüsseln
  Screen.Cursor := crHourGlass;
  Memo1.Text := DecodeText(Memo2.Text,Edit1.Text);
  Screen.Cursor := crDefault;
end;

procedure TFrmCipher.Button3Click(Sender: TObject);// Datei verschlüsseln
var
  Modus : word;
begin
  Screen.Cursor := crHourGlass;
  If RadioButton1.Checked then Modus := 0 else
  If RadioButton2.Checked then Modus := 1 else
  If RadioButton3.Checked then Modus := 2 else
  begin
  ShowMessage(ErrorMessage);
  exit;
  end;
  EncodeFile(Edit2.Text,Edit3.Text,Edit1.Text,Modus);
  Screen.Cursor := crDefault;
end;

procedure TFrmCipher.Button4Click(Sender: TObject);// Datei entschlüsseln
var
  Modus : word;
begin
  Screen.Cursor := crHourGlass;
  If RadioButton1.Checked then Modus := 0 else
  If RadioButton2.Checked then Modus := 1 else
  If RadioButton3.Checked then Modus := 2 else
  begin
  ShowMessage(ErrorMessage);
  exit;
  end;
  DecodeFile(Edit2.Text,Edit3.Text,Edit1.Text,Modus);
  Screen.Cursor := crDefault;
end;

end.
Irgendwas muss da doch falsch sein. Ich weiß nur nicht so genau was.

Und noch etwas: Ich habe auf das Auffüllen mit Zufallsdaten verzichtet, weil ich sonst irgendwann an einem Punkt ankomme, an dem ich wahrscheinlich selbst nicht mehr durch den Code durchsteige (was jetzt schon schwierig ist) und ich doch mal denke, dass der Plaintext ansonsten ja auch nicht so known ist, oder? Abgesehen davon hab ich von der Verschlüsselung an sich zu wenig Ahnung um nun sagen zu können, wie sicherheitsrelevant das ist.

THX for your help,
Daniel! :dancer:

Luckie 3. Okt 2003 03:50

Re: Dateien verschlüsseln - aber wie?
 
also ich weiß, ja nicht, wie du damit klar gekommen bist, aber wenn ich das mache:
Delphi-Quellcode:
uses
  Hash, Cipher, DECUtil;

...
...
...

initialization
   RegisterDECClasses([TCipher_Blowfish, TCipher_SCOP, TCipher_Rijndael, THash_MD4, THash_SHA1, THash_RipeMD128]);
Fann bekomme ich folgende Fehlermeldungen:
Code:
[Fehler] Unit1.pas(74): Undefinierter Bezeichner: 'RegisterDECClasses'
[Fehler] Unit1.pas(74): Ordinaltyp erforderlich
[Fehler] Unit1.pas(74): Inkompatible Typen: 'Integer' und 'Class reference'[Fehler] Unit1.pas(74): Inkompatible Typen: 'Integer' und 'Class reference'[Fehler] Unit1.pas(74): Inkompatible Typen: 'Integer' und 'Class reference'[Fehler] Unit1.pas(74): Inkompatible Typen: 'Integer' und 'Class reference'
Zeile 74 ist die oben gepostete Zeile.

Und was meinst du damit:
Zitat:

der für die Konvertierung des Passwortes in den Sessionkey benutzt wird,
Mach dies das DEC automatisch?

Ich glaube, wenn wir es geschaft haben mit dem DEC umzugehen, dann stelle ich mein Programm, zum Verschlüsseln einer Datei hier rein, als Anschauungsobjekt. :roll:

Luckie 3. Okt 2003 05:13

Re: Dateien verschlüsseln - aber wie?
 
So, irgendwie hab eich es jetzt geschaft:
Delphi-Quellcode:
procedure EncodeFile(Filename, PW: String; hWnd: THandle);
var
  SrcStream: TStreamProgressAdapter;
  DestStream: TFileStream;
begin
  SrcStream := TStreamProgressAdapter.Create(TFileStream.Create(Filename, fmOpenRead or fmShareDenyNone), 0, hWnd);
  if Assigned(SrcStream) then
  begin
    try
      DestStream := TFileStream.Create(Filename+EXTENSION, fmCreate);
      if Assigned(DestStream) then
      begin
        try
          with CipherClass.Create(PW, nil) do
          begin
            Mode := cmCFB;
            InitKey(PW, nil);
            EnCodeStream(SrcStream, DestStream, -1);
          end;
        finally
          FreeAndNil(DestStream);
        end;
      end;
    finally
      FreeAndNil(SrcStream);
    end;
  end;
end;
Mit:
Delphi-Quellcode:
CipherClass: TCipherClass = TCipher_Blowfish;
Das ganze ist jetzt noch ohne Hash der original Datei und ohne Datei-Header und es ist noch nicht in einem Thread, was auch noch kommt.

daniel-volk 3. Okt 2003 08:15

Re: Dateien verschlüsseln - aber wie?
 
@ Luckie:
Das was ich gepostet hab ist mein gesamter Code. Du musst nur noch uses hinzufügen, ansonsten nichts. initialization lass weg! Das geht eh nicht.

Ich hatte auch schon vor meinen Code zur Verfügung zu stellen, aber vorher will ich es noch irgendwie schaffen diese Prüfsumme (hash-Wert) in den Header zu schreiben und beim Entschlüsseln wieder zu lesen.

Kannst du mir da helfen?

Danke,
Daniel. :mrgreen:

negaH 3. Okt 2003 09:54

Re: Dateien verschlüsseln - aber wie?
 
Zitat:

Fann bekomme ich folgende Fehlermeldungen:
Code:

[Fehler] Unit1.pas(74): Undefinierter Bezeichner: 'RegisterDECClasses'
[Fehler] Unit1.pas(74): Ordinaltyp erforderlich
[Fehler] Unit1.pas(74): Inkompatible Typen: 'Integer' und 'Class reference'[Fehler] Unit1.pas(74): Inkompatible Typen: 'Integer' und 'Class reference'[Fehler] Unit1.pas(74): Inkompatible Typen: 'Integer' und 'Class reference'[Fehler] Unit1.pas(74): Inkompatible Typen: 'Integer' und 'Class reference'


Zeile 74 ist die oben gepostete Zeile.
Shit, alles zurück !!
Das kann garnicht funktionieren da ihr leider die "alte" Version vom DEC habt. In dieser wurden die registrierten Listen der Algorithmen für die Cipher/Hashs separat verwaltet. Erst in meiner Version vom DEC habe ich dies vereinfacht und alle Klassen werden gemeinsam verwaltet.
Also Asche auf mein Haupt und Entschuldigung für die Verwirrungen die ich damit gestifftet habe, es tut mir wirklich leid.

Vielleicht sollte ich wirklich anfangen und das DEC nochmals verbessern, und die ganzen neuen Ideen und Designänderungen der letzten 4 Jahre berücksichtigen. Ich hatte schon mehrmals geplant DEC komplett neu und besser zu machen, habe es aber immer wieder weg geschoben.
Es gibt einige Dinge die ich alleine auf Grund meines besseren Verständnisses der Kryptographie heute nicht mehr so bauen würde wie im DEC.

Gruß Hagen

daniel-volk 3. Okt 2003 13:14

Re: Dateien verschlüsseln - aber wie?
 
HIIIILLLFFFEEE!!!! :shock:

Ich habs jetzt ja fast geschafft (siehe Quellcode auf der vorherigen Seite). Aber wie kann ich einen String (mit dem Original-Hash-Wert der Datei) in den Dateiheader der verschlüsselten Datei schreiben, diesen dann vor dem Entschlüsseln wieder auslesen und auch wieder entfernen?????
Das ist mein einziges Problem, das es noch gibt. :gruebel:

@ Hagen:
Wenn ich eine Datei wipen will, kann ich das so machen?:
:roll:
Delphi-Quellcode:
with DefCipherClass.Create('',nil)
                 do begin
                      try
                        InitKey('',nil);
                        CodeFile(Input, Input, paWipe);
                        DeleteFile(Input);
                      finally
                        Free;
                      end;
                    end;
Scheinbar wird die Datei dann überschrieben - aber nur gelöscht, wenn ich noch DeleteFile hinzufüge.
Oder ist es besser, wenn ich das Wipen mit der TRandom-Funktion mache? :?:

THX,
Daniel. :wiejetzt:

Luckie 3. Okt 2003 14:51

Re: Dateien verschlüsseln - aber wie?
 
Zitat:

Zitat von daniel-volk
@ Luckie:
initialization lass weg! Das geht eh nicht.

Mann, dann sag das doch. Ich habe mich zwei Stunden damit rumgeschlagne und den Fehler bei mir gesucht, dabei lag der bei Hagen. Hättest du das gleich gesagt, hätte ich mir das sparen können und Hagen hätte gewußt, dass er da was falsches gepostet hatte.
Zitat:

aber vorher will ich es noch irgendwie schaffen diese Prüfsumme (hash-Wert) in den Header zu schreiben und beim Entschlüsseln wieder zu lesen.
Kannst du mir da helfen?
Heute Abend sollte ich soweit sein, dass ich eine funktioniernde Beta präsentieren kann.

Das sichere Löschen der Datei, ist ein Thema für sich. Im Moment neige ich dazu dass der benutzer selber dafür zu sorgen hat, mittels eines anderen Programmes pder was weiß ich wie.

@Hagen: Ich arbeite hier mit der 3.0, Datum habe ich jetzt nicht im Kopf.

daniel-volk 3. Okt 2003 14:55

Re: Dateien verschlüsseln - aber wie?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich kapier's nicht! Das Ding will einfach nicht richtig mit dem Header umgehen.

Ich poste euch hier mal meinen Code. Vielleicht könnt ihr das Problem ja beheben:
Wenn ich eine Datei verschlüssel, dann geht alles. Nur beim Entschlüsseln treten dann Fehler ohne Ende auf! Und zwar meiner Meinung nach beim Auslesen des Headers. :(

Nu gut, wer mir hilft das Problem mit dem Header zu beheben, der darf meinen Code natürlich auch für eigene Zwecke verwenden!

THX,
Daniel. :bounce2:

Luckie 3. Okt 2003 14:59

Re: Dateien verschlüsseln - aber wie?
 
Ich sagte doch, gib mir noch etwas Zeit, dann bin ich fertig. Ideen wie ich den Header da dranbekomme habe ich schon, muß mir nur noch ausdenken, wie ich es am übersichtlichsten und am leicht verständlichsten code.

Luckie 3. Okt 2003 15:40

Re: Dateien verschlüsseln - aber wie?
 
Wie komme ich von der CipherClass (z.B. TCipher_Blowfish) zu CiperIdentity, um sie im Header zu speichern? Gleiche Frage für den Hash-Algo.

daniel-volk 3. Okt 2003 17:01

Re: Dateien verschlüsseln - aber wie?
 
Wieso willst du das machen? Du kannst doch einfach in deinen Record direkt eine Variable vom Typ TCipherClass einbauen. Ist doch viel einfachen.

MfG.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:17 Uhr.
Seite 1 von 3  1 23      

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