![]() |
String mit Blowfish verschlüsseln
Ich habe die Komponente dcpcrypt eingebunden und möchte nun einen best. String mithilfe eines Sicherheitspasswortes mit Blowfish verschlüsseln(und auch entschlüsseln), so wie es im irc oft verwandt wird..
Leider bin ich gerade ins stocken geraten und bitte daher euch um Hilfe! Ich weiß nicht genau wie ich diese Komponente anwenden soll um mein gewünschtes Ergebniss zu erzielen.. Vielen Dank schonmal! |
Re: String mit Blowfish verschlüsseln
Hallo,
dcpcrypt sagt mir nichts, daher ein Alternativvorschlag. ;) Das DEC (Delphi Encryption Compendium) von Hagen Reddmann ( ![]() Damit geht das sehr einfach (ich habe das mal in eine Funktion gepackt):
Delphi-Quellcode:
Evtl. empfiehlt es sich auch, den verschlüsselnden String als var-Parameter zu übergeben.
function EncodeString(const Text: String; const Password: String): string;
begin with TCipher_Blowfish.Create(Password, nil) do try Text := EncodeString(Text); finally Free; end; Result := Text; end; Für's Entschlüsseln musst du DecodeString nutzen. |
Re: String mit Blowfish verschlüsseln
Ich hatte im Kopf, dass man es so aufrufen muss:
Delphi-Quellcode:
Auf jeden Fall mal den Rückgabewert nach Result und nicht nach Text :P
function EncodeString(const Text: String; const Password: String): string;
begin with TCipher_Blowfish.Create(Password, nil) do try Init; Result := EncodeString(Text); Done; finally Free; end; end; |
Re: String mit Blowfish verschlüsseln
Zitat:
Ich habe übrigens die Angewohnheit in Delphi, "Result" immer am Ende zu verwenden, daher mache ich das so. Ich hatte es so in Erinnerung, aber das müsste man mal ausprobieren, wenn man Zeit/Lust hat. :stupid: |
Re: String mit Blowfish verschlüsseln
Habe nun die Unit DECCipher eingebunden und per DECCipher.TCipher_Blowfish Zugriff auf den Blowfish type...
Jetzt fänt es aber schon hier an: TCipher_Blowfish.Create(Password, nil) --Too many actual paramters Vielleicht wisst ihr ja was ich falsch mache |
Re: String mit Blowfish verschlüsseln
Lass einfach das nil weg :P
|
Re: String mit Blowfish verschlüsseln
eben nicht :D
die Prozedur hat überhaupt keine Parameter .. ist laut Azeige nur ein constructor |
Re: String mit Blowfish verschlüsseln
In Version 5.1c, obiger Link geht das so
Delphi-Quellcode:
Ich empfehle aber es bischen sicherer und eventuell komfortabler zu machen.
with TCipher_Blowfish.Create do
try Init(Password); Result := EncodeBinary(Text, TFormat_Copy); finally Free; end;
Delphi-Quellcode:
Wir benutzen eine randomisierte KDF -> Key Derivation Function -> Schlüsselableitungsfunktion um aus dem Passwort einen sicheren und jedesmal anderen Sessionkey zu erzeugen. Dies schützt das Passwort des Benutzers vor sehr vielen Angriffen, zb. auch Rainbow Tabellen, Choosen Plaintext, Choosen Ciphertext Angriffen usw. Verschlüsselt man die gleichen Daten mit dem gleichen Passwort mehrmals so wird man erkennen das der Output immer komplett anders ist.
uses DECUti, DECCipher, DECHash, DECFmt, DECRandom;
interface var ACipherClass: TDECCipherClass = TCipher_Blowfish; ACipherMode: TCipherMode = cmCFS8; AHashClass: TDECHashClass = THash_SHA1; ATextFormat: TDECFormatClass = TFormat_MIME64; AKDFIndex: LongWord = 1; function Encrypt(const AText: String; const APassword: String): String; overload; function Decrypt(const AText: String; const APassword: String): String; overload; implementation function Encrypt(const AText: String; const APassword: String): String; var ASalt: Binary; AData: Binary; begin with ValidCipher(ACipherClass).Create, Context do try ASalt := RandomBinary(16); Mode := ACipherMode; Init(ValidHash(AHashClass).KDFx(APassword, ASalt, KeySize, TFormat_Copy, AKDFIndex)); AData := ASalt + EncodeBinary(AText) + CalcMAC; Result := ValidFormat(ATextFormat).Encode(AData); finally Free; ProtectBinary(ASalt); ProtectBinary(AData); end; end; function Decrypt(const AText: String; const APassword: String): String; var ASalt: Binary; AData: Binary; ACheck: Binary; ALen: Integer; begin with ValidCipher(ACipherClass).Create, Context do try ASalt := ValidFormat(ATextFormat).Decode(AText); ALen := Length(ASalt) -16 -BufferSize; AData := System.Copy(ASalt, 17, ALen); ACheck := System.Copy(ASalt, ALen +17, BufferSize); SetLength(ASalt, 16); Mode := ACipherMode; Init(ValidHash(AHashClass).KDFx(APassword, ASalt, KeySize, TFormat_Copy, AKDFIndex)); Result := DecodeBinary(AData); if ACheck <> CalcMAC then raise Exception.Create('Invalid data'); finally Free; ProtectBinary(ASalt); ProtectBinary(AData); ProtectBinary(ACheck); end; end; initialization RandomSeed; // initialisiere kryptographisch sicheren Zufallsgenerator in DECRandom.pas mit zufälligem Startwert finalization end. Der Vorteil der KDF ist das sie intern einen Hash benutzt, mit einem Salt aus dem Passwort einen randomisierten Sessionkey erzeugt und nicht zuletzt das der erzeugte Sessionkey exakt so lang an Bytes ist wie der Cipher als Key ausnutzen kann. Man reduziert ja bei zu kurzen Keys die Gesamtsicherheit des Ciphers und bei zu langem Passwort vernichtet man zusätzliche Sicherheit da die zusätzlichen Schlüsselbits ncht vom Cipher ausgwertet werden können. Die KDF beseitigt all diese Probleme. Man sollte immer eine KDF benutzen ! Wir benutzen den Ciphermode cmCFS8. Das ist ein Modus der Byteweise verschlüsselt. Wenn Blowfish also 16 Bytes als Blockgröße hat so wird im 1 Bytes Versatz jedes Datenbyte 16 mal verschlüsselt. Das ist besonderst anzuraten bei der Verschlüsselung kurzer Nachrichten, eben Strings. Wir wandeln die binären Daten nach ihrer Verschlüsselung in ein anders Textformat um, damit es auch über 7Bit Datenkanäle ohne Datenverlust übertragbar ist. In diesem Falle benutzen wir das MIME-Base64 Format. Wurden die Daten manipuliert so wird man das bei der Entschlüsselung mitbekommen. Du kannst zum Debugging auch mal TFormat_HEX benutzen um die Daten als HEX-String dir anschauen zu können. Beim TFormat_Copy bleiben die Daten 1 zu 1 in ihrer binären Form erhalten. Benuzt du TFormat_PGP ist es das Gleiche wir MIME64 nur das hinten dran noch eine 24Bit Prüfsumme drangehangen wird. Wir benutzen globale initialisierte Variablen, damit kannst du alle wichtigen Parameter der Funktionen einstellen. Das ist dann wichtig wenn man zb. feststellen würde das Blowfish oder SHA1 geknackt wurden. Man kann dann sehr schnell auf andere Verfahren ausweichen. Durch das Einbinden von DECRandom.pas benutzen alle internen DEC Random Funktionen einen kryptographisch sicheren Zufallsgenerator. In der Initialization rufen wir RandomSeed; auf, das hat eine ähnliche Wirkung wie Randomize; Allerdings werden die Initialisierungsparameter von RandomSeed; dann aus zb. TickCounter und Datum Uhrzeit des Rechners ermittelt. Das ist immer noch nicht absolut sicher. Besser wäre es zb. 1024 Bytes an Keyboard und Mouse Ereignissen zu sammeln, die durch den Anwender "zufällig" erzeugt wurden. Dann mit RandomSeed(ABuffer, SizeOf(ABuffer)) den Zufallsgenerator initialisieren, wobei ABuffer diese Events enthält. Ab diesem Moment ist das Ganze wirklich sicher, sowohl von den kryptrographischen Verfahren, Protokollen her gesehen wie auch technologisch in der Implementierung dergleichen. Gruß Hagen PS: den Source oben habe ich gerade eben eingetippt, es könnten also kleine Tippfehler drinnen sein. PPS: Über die Variable AKDFIndex kannst du die Schlüsselableitungsfunktion serialisieren. Wenn du also AKDFIndex zb. auf 25769 setzen würdest so werden andere Sessonkeys zum Password erzeugt als mit AKDFIndex = 1 usw. Das ist vorteilhaft wenn man obigen Source in verschiedenen Anwendungen benutzen möchte deren Daten untereinander nicht entschlüsselbar sein sollen. Dann sollten diese Anwendungen unterschiedliche KDF Indizes benutzen. PPPS: es gibt noch eine Verbesserungsmöglichkeit. Nach .EncodeBinary() kann man mit .CalcMAC(TFormat_Copy); noch eine "Prüfsumme" der verschlüsselten Daten erzeugen lassen. Diese Prüfsumme wird einfach hinten an Result drangehangen. In Decrypt() kann man dann diese Prüfsumme extrahieren und dann nach .DecodeBinary() wieder mit .CalcMAC(TFormat_Copy) == extrahierte Prüfsumme vergleichen. Damit hat man also eine Überprüfung ob die Daten unverfälscht sind bzw. das gleiche Passwort benutzt wurde. Das besondere dieser Prüfsumme ist es das sie sicherer ist als zb. ein Hash oder eine CRC die man über die Daten gezogen hat. Denn diese Prüfsumme ist zufällig -> KDF und abhängig von den unverschlüsselten Daten wie auch den verschlüsselten Daten und vom sicheren internen Status des Ciphers. Soll heisen das das Vorhandensein dieser prüfsumme nicht ausgenutzt werden kann um zb. Brute Force Angriffe zu beschleunigen oder um überhaupt überprüfen zu können ob man das richtige Passwort per Brute Force gefunden hat. Ich habs mal eben gerade noch eingebaut. Man sieht das man mit DEC sehr einfache Sourcen benutzen kann, will man es aber wirklich sicher so muß man schon ein bischen mehr Aufwand treiben. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:19 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