Thema: Delphi DEC 5.1 kein "Initkey"

Einzelnen Beitrag anzeigen

Benutzerbild von negaH
negaH

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

Re: DEC 5.1 kein "Initkey"

  Alt 3. Apr 2006, 07:23
Im DECTest Projekt -> \DEC\D?\DECTest\DECTest.bpg findet sich dann auch eine Demonstration für die Verschlüsselung von Dateien.

Delphi-Quellcode:
uses DECRandom;

procedure DemoCipherFile;
// demonstriert eine sehr sichere Anwendung von Verschlüsselungen, Hashfunktionen,
// Key Derivation Functions und Zufallsdaten.


  procedure EncodeFile(const AFileName: String; const APassword: Binary;
                       ACipher: TDECCipherClass = nil; AMode: TCipherMode = cmCTSx;
                       AHash: TDECHashClass = nil);
  // Die Datei wird verschlüsselt danach überschrieben und gelöscht.
  // Die verschlüsselte Datei wurde mit einem Session Passwort verschlüsselt das mit Hilfe
  // einer KDF = Key Derivation Funktion und einem Zufallswert erzeugt wurde.
  // Der Zufallswert == Seed ist 128 Bits groß und wird in der verschlüsselten Datei gespeichert.
  // Dieser stellt sicher das es unmöglich wird das Passwort zu knacken und randomisiert zusätzlich
  // die Daten der Vershlüsselung. Am Ende der verschlüsselten Datei wird eine Prüfsumme gespeichert
  // mit Hilfe einer CMAC = Cipher Message Authentication Code.
  // Die verschlüsselte Datei enthält am Anfang zusätzlich noch Informationen zum
  // verwendeten Cipher-/Hash Algorithmus, CipherMode usw. Dies ermöglicht bei der Entschlüsselung der
  // Datei die automatische Auswahl der Algorithmen.
  // Werden für Cipher und oder Hash == nil übergeben so wird der Standard Cipher/Hash benutzt.
  // Das benutze Session Passwort hat immer Zufällige Eigenschaften, es verhält sich wie Zufallsdaten.
  // Nur derjenige der den Zufalls-Seed und APassword kennt kann die Daten korrekt entschlüsseln.
  var
    Dest: TStream;

    procedure Write(const Value; Size: Integer);
    begin
      Dest.WriteBuffer(Value, Size);
    end;

    procedure WriteByte(Value: Byte);
    begin
      Write(Value, SizeOf(Value));
    end;

    procedure WriteLong(Value: LongWord);
    begin
      Value := SwapLong(Value);
      Write(Value, SizeOf(Value));
    end;

    procedure WriteBinary(const Value: Binary);
    begin
      WriteByte(Length(Value));
      Write(Value[1], Length(Value));
    end;

  var
    Source: TStream;
    Seed: Binary;
  begin
    ACipher := ValidCipher(ACipher);
    AHash := ValidHash(AHash);

    Seed := RandomBinary(16);

    Source := TFileStream.Create(AFileName, fmOpenReadWrite);
    try
      Dest := TFileStream.Create(AFileName + '.enc', fmCreate);
      try
        with ACipher.Create do
        try
          Mode := AMode;
          Init(AHash.KDFx(APassword, Seed, Context.KeySize));

          WriteLong(Identity);
          WriteByte(Byte(Mode));
          WriteLong(AHash.Identity);
          WriteBinary(Seed);
          WriteLong(Source.Size);
          EncodeStream(Source, Dest, Source.Size);
          WriteBinary(CalcMAC);
        finally
          Free;
        end;
      finally
        Dest.Free;
      end;
      ProtectStream(Source);
    finally
      Source.Free;
    end;
    DeleteFile(AFileName);
  end;

  procedure DecodeFile(const AFileName: String; const APassword: Binary);
  // entschüssele eine Datei die vorher mit EncodeFile() verschlüsselt wurde.
  var
    Source: TStream;

    procedure Read(var Value; Size: Integer);
    begin
      Source.ReadBuffer(Value, Size);
    end;

    function ReadByte: Byte;
    begin
      Read(Result, SizeOf(Result));
    end;

    function ReadLong: LongWord;
    begin
      Read(Result, SizeOf(Result));
      Result := SwapLong(Result);
    end;

    function ReadBinary: Binary;
    begin
      SetLength(Result, ReadByte);
      Read(Result[1], Length(Result));
    end;

  var
    Dest: TStream;
  begin
    Source := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyNone);
    try
      try
        Dest := TFileStream.Create(ChangeFileExt(AFileName, ''), fmCreate);
        try
          try
            with CipherByIdentity(ReadLong).Create do
            try
              Mode := TCipherMode(ReadByte);
              Init(HashByIdentity(ReadLong).KDFx(APassword, ReadBinary, Context.KeySize));
              DecodeStream(Source, Dest, ReadLong);
              if ReadBinary <> CalcMAC then
                raise EDECException.Create('Invalid decryption');
            finally
              Free;
            end;
          except
            ProtectStream(Dest);
            raise;
          end;
        finally
          Dest.Free;
        end;
      except
        DeleteFile(ChangeFileExt(AFileName, ''));
        raise;
      end;
    finally
      Source.Free;
    end;
  end;

var
  FileName: String;
begin
  WriteLn(#13#10'File En/Decryption test');

// stelle Standard Cipher/Hash ein.
  SetDefaultCipherClass(TCipher_Rijndael);
  SetDefaultHashClass(THash_SHA1);
// Stelle die Basis-Identität der Cipher/Hash Algorithmen auf einen Anwendungsspezifischen Wert ein.
// Damit ist sichergestellt das nur Dateien die mit dieser Anwendung verschlüsselt wurden auch wieder
// entschlüselbar sind. Dei Verschlüsselungsfunktion oben speichert ja die Identity des benutzen
// Ciphers/Hashs in der verschlüsselten Datei ab. Beim Entschlüsseln mit DecodeFile() werden diese
// Identities geladen und aus den Regstrierten DECClassen geladen.
  IdentityBase := $84485225;
// alle benutzten und ladbaren Cipher/Hash müssen registriert werden.
  RegisterDECClasses([TCipher_Rijndael, THash_SHA1]);
// obige Sourcezeilen sollten normalerweise im Startup der Anwendung erfolgen.

  FileName := ChangeFileExt(ParamStr(0), '.test');
  EncodeFile(FileName, 'Password');
  DecodeFile(FileName + '.enc', 'Password');
end;

// und Anwendung eines besseren Keysetups

procedure DemoCipher(Index: Integer);
// demonstrate en/decryption with cipher Blowfish and use of a
// secure Hash based random KDF -> Key Derivation Function
var
  Seed, Encoded, Decoded: Binary;
begin
  Seed := RandomBinary(16);

  with TCipher_Blowfish.Create do
  try
    Init(THash_SHA1.KDFx('Password here', Seed, Context.KeySize));
    Encoded := EncodeBinary('Secret data here', TFormat_MIME64);
  finally
    Free;
  end;

  with TCipher_Blowfish.Create do
  try
    Init(THash_SHA1.KDFx('Password here', Seed, Context.KeySize));
    Decoded := DecodeBinary(Encoded, TFormat_MIME64);
  finally
    Free;
  end;

  WriteLn(#13#10'Demo Cipher #', Index);
  WriteLn('encoded: ', Encoded);
  WriteLn('decoded: ', Decoded);
end;

initialization
  RandomSeed; // randomize DEC's own RNG
end.
Gruß Hagen
  Mit Zitat antworten Zitat