AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

String mit Blowfish verschlüsseln

Ein Thema von terminator1000 · begonnen am 4. Nov 2007 · letzter Beitrag vom 4. Nov 2007
Antwort Antwort
terminator1000

Registriert seit: 2. Feb 2007
26 Beiträge
 
#1

String mit Blowfish verschlüsseln

  Alt 4. Nov 2007, 02:53
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!
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: String mit Blowfish verschlüsseln

  Alt 4. Nov 2007, 09:30
Hallo,

dcpcrypt sagt mir nichts, daher ein Alternativvorschlag.

Das DEC (Delphi Encryption Compendium) von Hagen Reddmann (DEC_5_1c.zip) enthält eine Vielzahl von Verschlüsselungs- und Hashalgorithmen. Vielleicht hast du davon schon gehört.
Damit geht das sehr einfach (ich habe das mal in eine Funktion gepackt):

Delphi-Quellcode:
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;
Evtl. empfiehlt es sich auch, den verschlüsselnden String als var-Parameter zu übergeben.

Für's Entschlüsseln musst du DecodeString nutzen.
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#3

Re: String mit Blowfish verschlüsseln

  Alt 4. Nov 2007, 09:48
Ich hatte im Kopf, dass man es so aufrufen muss:

Delphi-Quellcode:
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;
Auf jeden Fall mal den Rückgabewert nach Result und nicht nach Text
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: String mit Blowfish verschlüsseln

  Alt 4. Nov 2007, 10:10
Zitat von Zacherl:
Auf jeden Fall mal den Rückgabewert nach Result und nicht nach Text
Ups, danke. Ist korrigiert. Das hing damit zusammen, da ich erst überlegt hatte, "Text" als var-Parameter zu übergeben und mich dann doch so entschieden habe.
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.
  Mit Zitat antworten Zitat
terminator1000

Registriert seit: 2. Feb 2007
26 Beiträge
 
#5

Re: String mit Blowfish verschlüsseln

  Alt 4. Nov 2007, 12:42
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
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#6

Re: String mit Blowfish verschlüsseln

  Alt 4. Nov 2007, 13:09
Lass einfach das nil weg
  Mit Zitat antworten Zitat
terminator1000

Registriert seit: 2. Feb 2007
26 Beiträge
 
#7

Re: String mit Blowfish verschlüsseln

  Alt 4. Nov 2007, 13:22
eben nicht

die Prozedur hat überhaupt keine Parameter .. ist laut Azeige nur ein constructor
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#8

Re: String mit Blowfish verschlüsseln

  Alt 4. Nov 2007, 15:44
In Version 5.1c, obiger Link geht das so

Delphi-Quellcode:
with TCipher_Blowfish.Create do
try
  Init(Password);
  Result := EncodeBinary(Text, TFormat_Copy);
finally
  Free;
end;
Ich empfehle aber es bischen sicherer und eventuell komfortabler zu machen.

Delphi-Quellcode:
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.
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.
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.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:56 Uhr.
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