Einzelnen Beitrag anzeigen

andreas baun

Registriert seit: 10. Dez 2003
4 Beiträge
 
#3

Re: Text verschlüsseln mit BlowFish und SHA1

  Alt 11. Dez 2003, 05:35
@Hagen
erst mal besten Dank für die schnelle und informative Antwort.

1. Byte- oder BlockChiper ...
Definitionirrtum von mir, ich dachte ByteChiper sind die,
die mit Buffer=1Byte arbeiten. Hier geht’s aber mehr um
den Ciphermode.

2. Delphirandom
diesbezüglich brauche ich mir keine weiteren Sorgen (unsicher und so) machen?

Ich habe versucht das "Besprochene" Testweise (mit DEC) nachzubauen.

Bin dabei auf Folgendes gestoßen, wenn man den CBC-Mode anwendet,
hat man das Problem, dass der verschlüsselt gespeicherter Sessionkey
falsch entschlüsselt wird. Lieg daran, das in dem Mode die letzten
4 Bytes (Sessionkey) anderes behandelt werden, weil 20 mod 8 <> 0 ist
(ich kanns leider nicht besser erklären).
Ich konnte mir natürlich helfen, in dem ich beim Sessionkey-Entschlüsseln einfach
4 bytes mehr mitgenommen habe. Du hast bestimmt besseren Vorschlag
Im CFB-Mode tritt das Problem natürlich nicht auf, da Byte für Byte entschlüsselt wird.
Ich dachte nur, dass der CBC sicherer + schneller wäre, oder?

Den Test-Code lege ich bei, vielleicht (wenn’s nicht allzu viel Arbeit macht) "fliegst Du mal drüber"?

Delphi-Quellcode:

var
  // "Virtuelle Datei" Aufbau in Bytes:
  // 0-19 : Salt
  // 20-39: SKey
  // 40-XX: Message
  g_File: Pointer;
  g_FileSize: Integer;


procedure TForm1.EncodeClick(Sender: TObject);
var
  hash: THash_SHA1;
  fish: TCipher_Blowfish;
  salt: array[0..19] of Byte;
  temp: Pointer;
begin
  //Zufallsdaten erzeugen
  RndXORBuffer(RndTimeSeed, salt, sizeof(salt));

  //Sessionskey erzeugen
  hash:= THash_SHA1.Create(nil);
  hash.Init;
  hash.Calc(salt, sizeof(salt));
  hash.Calc(PChar('Who is John Galt?')^, 17);
  hash.Done;

  //Temp. Speicher fur SKey + Message reservieren
  GetMem(temp, hash.DigestKeySize + Length(Memo1.Text) + 1);

  //SKey erstmal nach temp kopieren, soll ja mit Message in einem Rutsch verschlüsselt werden
  Move(hash.DigestKey^, temp^, hash.DigestKeySize);
  //den Text der Nachricht hollen
  SendMessage(Memo1.Handle, WM_GETTEXT, Length(Memo1.Text) + 1, LongInt(PChar(temp) + hash.DigestKeySize));

  //Speicher für die "virtuelle Datei", hierdrüber soll der Test-Austausch erfolgen
  g_FileSize:= sizeof(salt) + hash.DigestKeySize + Length(Memo1.Text);
  GetMem(g_File, g_FileSize + 1);
  //Salt unverschlüsselt in die "Datei" schreiben
  Move(salt, g_File^, sizeof(salt));

  //den Fish erstellen und initialzieren
  fish:= TCipher_Blowfish.Create('', nil);
  fish.Mode:= cmCBC;
  fish.Init(hash.DigestKey^, hash.DigestKeySize, nil);
  //Datei (ohne salt) verschlüsseln
  fish.EncodeBuffer(temp^, PChar(PChar(g_File) + 20)^, g_FileSize - sizeof(salt));
  //Spasseshalber den verschl. Text ausgeben
  Memo2.Text:= StrToFormat(pchar(g_File), g_FileSize, fmtHEX);
  //aufräumen sollte man auch nicht vergessen
  hash.Free;
  fish.Free;
  freemem(temp);
end;



procedure TForm1.DecodeClick(Sender: TObject);
var
  hash: THash_SHA1;
  fish: TCipher_Blowfish;
  temp: Pointer;

  key2: array[0..19+4] of Byte;//4 Byte mehr wegen CBC
begin

  //Sessionskey erzeugen
  hash:= THash_SHA1.Create(nil);
  hash.Init;
  hash.Calc(g_File^, 20); //den Salt-Wert nicht vergessen
  hash.Calc(PChar('Who is John Galt?')^, 17);
  hash.Done;

  //Chiper erstellen und initialzieren
  fish:= TCipher_Blowfish.Create('', nil);
  fish.Mode:= cmCBC;
  fish.Init(hash.DigestKey^, hash.DigestKeySize, nil);
  //verschl. SKey decodieren
  fish.DecodeBuffer(PChar(g_File)[20], key2, 20+4);

  if not CompareMem(hash.DigestKey, @key2, 20) then
  begin
    ShowMessage('Invalid Password'#13#10 +
                'SKey1: ' + StrToFormat(PChar(hash.DigestKey), 20, fmtHEX) + #13#10 +
                'SKey2: ' + StrToFormat(PChar(@key2), 20, fmtHEX));
  end
  else begin
    GetMem(temp, g_FileSize - 20 + 1);
    fish.DecodeBuffer(pchar(g_File)[20], temp^, g_FileSize - 20);
    //den entschl. Text (ohne salt) ausgeben
    SendMessage(Memo3.Handle, WM_SETTEXT, 0, LongInt(@PChar(temp)[20]));

    FreeMem(temp);
  end;

  hash.Free;
  fish.Free;
end;
Gruß Andreas
PS: Ich hoffe, das ich mit meinem miserabelschlechten Deutsch die Ohren der Forumteilnehmer nicht
beleidigt habe.
  Mit Zitat antworten Zitat