Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   DEC mit ByteArray (https://www.delphipraxis.net/190867-dec-mit-bytearray.html)

Ghostwalker 15. Nov 2016 11:01


DEC mit ByteArray
 
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 :)

Sherlock 15. Nov 2016 11:53

AW: DEC mit ByteArray
 
Zitat:

Zitat von Ghostwalker (Beitrag 1353721)
Auf With hab ich bewußt verzichtet, damit ich erstmal durchblick was woher kommt und macht :)

Vergiss einfach, daß with existiert. Würde Dijkstra noch leben, würde er mit Sicherheit einen Aufsatz mit dem Titel "with statement considered harmful" verfassen. ;)

Sherlock

Ghostwalker 15. Nov 2016 13:46

AW: DEC mit ByteArray
 
@Sherlock

Ja...with verwirrt :) Deshalb verzicht ich auch meistens drauf.

Update:

Hab das ganze jetzt nochmal ordentlich in ein Objekt verpackt und wollte gleichzeitig
umsteigen auf Pointer:

Encrypt:

Delphi-Quellcode:
function TAESCryptor.Encrypt(var uncoded:pointer;var size:int64):pointer;
var
  ASalt: Binary;
  AData: TByteDynArray;
  APass: Binary;
  mac : Binary;
  cipher : TDECCipher;
  datalen : Int64;
  Hlp : pointer;

begin
  cipher := ValidCipher(fCipherClass).create;
  cipher.Mode := fCipherMode;
  //Salt erzeugen
  ASalt := RandomBinary(fSaltLen);
  //PW härten
  APass := ValidHash(fHashClass).KDFx(fpwd[1], Length(fpwd) * SizeOf(fpwd[1]), ASalt[1], Length(ASalt), Cipher.Context.KeySize, TFormat_Copy, fKDFIndex);

  //Initialisieren vom Cipher
  cipher.Init(APass);
  //Daten codieren
  datalen := Size;
  setLength(AData,datalen);

  cipher.Encode(uncoded^,AData[0],datalen-1);
  //Prüfsumme berechnen
  mac := cipher.CalcMAC();
  //Ergebnis zusammenschrauben
  datalen := length(AData);
  //Parameter an ergebnis anpassen !
  size := fSaltLen+datalen+Cipher.Context.BufferSize;
  //New Result-Pointer;
  GetMem(result,size);
  //Another one for Aritmethiks, so result is alwas at the begin
  hlp := Result;
  //First store the Salt
  move(ASalt[1],result^,fSaltLen);
  //Move on
  inc(Cardinal(hlp),fSaltLen);
  //Store the crypted data
  move(AData[0],hlp^,datalen);
  //Move on
  inc(Cardinal(hlp),datalen);
  //Store Mac
  move(mac[1],hlp^,Cipher.Context.BufferSize);

  //Cleanup internal data;
  cipher.free;
  ProtectBinary(ASalt);
  ProtectBuffer(AData[0],datalen);
  SetLength(AData,0);
  ProtectBinary(APass);
  ProtectBinary(mac);
end;
Decrypt
Delphi-Quellcode:
function TAESCryptor.Decrypt(var coded:Pointer;var size:int64):pointer;
var
  ASalt: Binary;
  AData: TByteDynArray;
  ACheck: Binary;
  APass: Binary;
  ALen: Integer;
  cipher : TDECCipher;
  hlp : Pointer;

begin
  //First we copy the pointer,so coded points always to the first byte
  hlp := coded;
  Cipher := ValidCipher(fCipherClass).Create;
  //Salt holen
  SetLength(ASalt,fSaltlen);
  move(hlp^,ASalt[1],fSaltLen);
  //Point to the begin of the crypted data
  Inc(Cardinal(hlp),fsaltLen);
  //Berechnung der tatsächlichen länge der veschlüsselten Daten
  ALen := Size-FSaltLen-cipher.Context.BufferSize;

  //Veschlüsselte Daten holen
  setLength(AData,ALen);
  move(hlp^,Adata[0],ALen);

  //Point to the begin of the MAC
  inc(Cardinal(hlp),ALen);

  //Checksumme holen
  SetLength(ACheck,Cipher.Context.BufferSize);
  move(hlp^,ACheck[1],Cipher.Context.BufferSize);
  //Pw save machen
  APass := ValidHash(fHashClass).KDFx(fpwd[1], Length(fpwd) * SizeOf(fpwd[1]), ASalt[1], fSaltLen, Cipher.Context.KeySize, TFormat_Copy, fKDFIndex);
  Cipher.Mode := fCipherMode;
  cipher.Init(APass);
  //Size auf größe des Ergebnisses setzen !
  size := Alen;
  //Result-Pointer erzeugen
  GetMem(result,size);
  //Daten decodieren
  Cipher.Decode(AData[0],result^,Alen-1);
  //Prüfsummenprüfung
  if (ACheck <> Cipher.CalcMac) then
    Raise eCryptorException.Create('Invalid Data');
  //Aufräumen
  cipher.Free;
  ProtectBinary(ASalt);
  ProtectBinary(ACheck);
  ProtectBinary(APass);
  ProtectBuffer(AData[0],alen);
  SetLength(AData,0);
end;
Aber irgendwo hauts mit der Länge noch net hin. Sobald ich meine Testdaten (immer die gleichen) verschlüssel und wieder decodiere hab ich 2 Zeichen zuviel hinten drann....

Ghostwalker 15. Nov 2016 14:14

AW: DEC mit ByteArray
 
ok...die -1 is schuld. War notwendig bei den Arrays (0 und 1 basierte im Mix).


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:36 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