Einzelnen Beitrag anzeigen

Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#1

DEC mit ByteArray

  Alt 15. Nov 2016, 11:01
MoinMoin,

nach langem Kampf hab ich es geschafft, die Beispiel-Routinen (von Lucky) für dyn. Bytearrays anzupassen.

Verschlüsseln.

Delphi-Quellcode:
function Encrypt(const AText: TByteDynArray; const APassword: WideString): TByteDynArray; overload;
var
  ASalt: Binary;
  AData: TByteDynArray;
  APass: Binary;
  mac : Binary;
  cipher : TDECCipher;
  resultlen,datalen : Int64;

begin
  cipher := ValidCipher(ACipherClass).create;
  //Salt erzeugen
  ASalt := RandomBinary(cSaltLen);
  //PW härten
  APass := ValidHash(AHashClass).KDFx(APassword[1], Length(APassword) * SizeOf(APassword[1]), ASalt[1], Length(ASalt), Cipher.Context.KeySize, TFormat_Copy, AKDFIndex);
  //Initialisieren vom Cipher
  cipher.Mode := ACipherMode;
  cipher.Init(APass);
  //Daten codieren
  datalen := Length(AText);
  setLength(AData,datalen);
  cipher.Encode(AText[0],AData[0],datalen-1);
  //Prüfsumme berechnen
  mac := cipher.CalcMAC();
  //Ergebnis zusammenschrauben
  datalen := length(AData);
  resultlen := csaltlen+datalen+cmaclen;
  setLength(result,resultlen);
  move(ASalt[1],result[0],csaltlen);
  move(AData[0],result[csaltlen],datalen);
  resultlen := csaltlen+datalen;
  move(mac[1],result[resultlen],cmaclen);

  //Cleanup internal data;
  cipher.free;
  ProtectBinary(ASalt);
  ProtectBuffer(AData[0],datalen);
  SetLength(AData,0);
  ProtectBinary(APass);
  ProtectBinary(mac);
end;
Entschlüsseln.

Delphi-Quellcode:
function Decrypt(const AText: TByteDynArray; const APassword: WideString): TByteDynArray; overload;
var
  ASalt: Binary;
  AData: TByteDynArray;
  ACheck: Binary;
  APass: Binary;
  ALen: Integer;
  cipher : TDECCipher;
  p : Int64;

begin
  Cipher := ValidCipher(ACipherClass).Create;
  //Salt holen
  SetLength(ASalt,csaltlen);
  move(AText[0],ASalt[1],csaltlen);
  //Berechnung der tatsächlichen länge der veschlüsselten Daten
  ALen := length(AText)-csaltlen-cmaclen;
  //Veschlüsselte Daten holen
  setLength(AData,ALen);
  move(Atext[csaltlen],Adata[0],ALen);
  //Checksumme holen
  SetLength(ACheck,cMacLen);
  p := cSaltlen+ALen;
  move(AText[p],ACheck[1],cMacLen);
  //Pw save machen
  APass := ValidHash(AHashClass).KDFx(APassword[1], Length(APassword) * SizeOf(APassword[1]), ASalt[1], Length(ASalt), Cipher.Context.KeySize, TFormat_Copy, AKDFIndex);
  Cipher.Mode := ACipherMode;
  cipher.Init(APass);
  //Daten decodieren
  SetLength(result,ALen);
  Cipher.Decode(AData[0],result[0],Alen-1);
  //Prüfsummenprüfung
  if (ACheck <> Cipher.CalcMac) then
    Raise Exception.Create('Invalid Data');
  //Aufräumen
  cipher.Free;
  ProtectBinary(ASalt);
  ProtectBinary(ACheck);
  ProtectBinary(APass);
  ProtectBuffer(AData[0],alen);
  SetLength(AData,0);
end;
Zum Testen hab ich TCipher_Rijndael benutzt (256-Bit), als Hash MD5. Salt-Länge 32,Mac-Länge 16;

Funktionieren tut das ganze soweit. Da ich aber nicht so vertraut mit DEC bin, wollt ich mal
die Spezialisten fragen, ob da noch Fehler, Probleme o.ä. drinn sind (auch Anregungen zur Optimierung sind gern gelsen.

Danke schonmal im Voraus

Auf With hab ich bewußt verzichtet, damit ich erstmal durchblick was woher kommt und macht
Uwe
e=mc² or energy = milk * coffee²

Geändert von Ghostwalker (15. Nov 2016 um 11:03 Uhr) Grund: Nachtrag
  Mit Zitat antworten Zitat