Szyfrowanie AES z wykorzystaniem SynaCrypt

0

Witam serdecznie, mam problem z szyfrowaniem aes.
Chciałem wykorzystać bibliotekę synapse w której jest unit SynaCrypt.
Poniżej kod który wywołuję:

function MyAes128Encrypt(DataIn,Key: AnsiString):AnsiString;
var Aes:TSynaAes;
begin
 Aes:=TSynaAes.Create(Key);
  try
    Result:= Aes.EncryptECB(DataIn);
  finally
    Aes.Free;
  end;
end;
 
function StrToHex(sString: ansistring): ansistring;
 var
  i : integer;
 begin
 result:='';
  for i:=1 to length(sString) do
     result:=result+' '+IntToHex( Ord(sString[i]) , 2);
 end;


procedure TForm1.Button1Click(Sender: TObject);
var aes:Tsynaaes;

begin
  Edit1.Text := strtohex(MyAes128Encrypt('aaabbbcccdddeeefff','1234567890123456'));
end;

Ciąg testowy to: aaabbbcccdddeeefff
klucz: 1234567890123456

W wyniku dostaję błędny zapis: 52 EB EE 07 76 B0 D0 E7 83 A1 B4 5F 4C A5 31 18

Dla porównania w kalkulatorze aes online
http://aes.online-domain-tools.com/
Mode: ECB (electronic codebook)

Dostaję:

52 eb ee 07 76 b0 d0 e7 83 a1 b4 5f 4c a5 31 18 f0 8c 53 ad 1b 7b c8 9e 2b 24 11 3f 2e b3 0c 07

Czyli jak widać znacznie dłuższy ciąg znaków w wyniku.
Domyślam się że ciąg wejściowy jest dopełniany znakiem o kodzie 0 (null) do pełnych 16-bajtowych bloków ale czemu tego nie robi synacrypt ?

Poratujecie jakimś pomysłem kawałkiem kodu.

1

z tego co widziałem TSynaAes.EncryptECB szyfruje tylko bloki 16 bajtowe i resztę ucina, jeśli chcesz użyć tej funkcji to musisz użyć pętli. Do uzupełniania bloków masz też funkcję PadString

0

Dziękuję za odpowiedź.
Wydaje mi się właśnie że w poprawnej implementacji aes ciąg wejściowy powinien być uzupełniany do pełnego bloku 16 bajtów.
Dajmy na to że mamy ciąg wejściowy 18 znaków „A” to po przejściu przez algorytm kodujący w wyniku powinienem otrzymać 32 bajty. Pierwszy blok to 16x „A” + drugi blok 16 bajtów to 2x „A” oraz 14x znaków o kodzie 0 (null).
Natomiast implementacja Synapsa na wejściu przyjmuje AnsiString a w tym typie dodanie znaku o kodzie 0 terminuje zawartość zmiennej więc nie mam jak nawet uzupełnić ciągu wejściowego.

1

Natomiast implementacja Synapsa na wejściu przyjmuje AnsiString a w tym typie dodanie znaku o kodzie 0 terminuje zawartość zmiennej więc nie mam jak nawet uzupełnić ciągu wejściowego.

Sam typ AnsiString może zawierać w sobie dowolną ilość znaków o kodzie 0, dlatego że fizyczna długość ciągu przechowywana jest niejawnie na kilku bajtach przed adresem pierwszego znaku (obok reference count); Tę liczbę wykorzystuje funkcja Length do zwrócenia długości łańcucha, bez konieczności każdorazowego zliczania wszystkich znaków;

Natomiast problem może pojawić się w przypadku, gdy implementacja jakiegoś algorytmu rzutuje typ AnsiString na PAnsiChar - można, bo łańcuchy AnsiString niejawnie są zakańczane nullem, a PAnsiChar wymaga tego znaku jako terminatora, bo nie używa niejawnych informacji o ilości znaków ciągu (bo to wskaźnik na pojedynczy znak); Wtedy pętla algorytmu (zakładając, że tak ktoś implementuje tokenizowanie znaków) przerywana jest po napotkaniu pierwszego znaku null; To samo uczyni funkcja StrLen, która zwróci długość łańcucha liczoną do pierwszego nulla;

Rozwiązaniem takiego bubla projektowego jest albo normalne tokenizowanie znaków (używając indeksów, nie pointerów), albo zapamiętanie wskaźnika na ostatni znak ciągu; Wtedy nie będzie problemu z szukaniem znaku o kodzie 0; Sam korzystam z takiego mechanizmu w funkcjach przeszukujących czy walidujących łańcuchy znaków (kodowanych w ANSI i UTF-8) i z nullami nie ma żadnego problemu.

0

Faktycznie ta linia kodu

move(pointer(InData)^, p^, 16);

zawsze "tnie" 16 bajtów do bufora i olewa resztę :/
Trochę fatalna implementacja jak na wejściu przyjmuje AnsiString ~2^31 znaków.

1 użytkowników online, w tym zalogowanych: 0, gości: 1