I can't decrypt old texts in version 5.1.1.0

Whenever you release a new version, I've had compatibility issues with previous versions and I need to modify my program.

I am now unable to decrypt texts created in versions prior to 5.1.1.0;

I upgrade from version 5.1.0.3 to 5.1.1.0 and when opening my project I received an error stating that the KeyLength property (of TAESEncryption) did not exist.

This property doesn't appear in the Object Inspector, but I can set it in the code.

I set it to the value I used, kl256, but I can't decrypt the encrypted texts in version 5.1.0.3.

I downgrade to version 5.1.0.3 and was able to decrypt the texts.

How can we solve this problem?

The properties of both versions are the same (except for the KeyLength, which I had to set in version 5.1.1.0 via code).

5.1.0.3:

5.1.1.0:

Hi,

There are 2 issues in your message.

The KeyLength property: I moved the TKeyLength type frome AES files to CryptoConst.pas so that it could be shared across the library without redefining it in several places. It looks like that this ‘external’ declaration removed the property from the graphical component. I was not aware of that ‘side effect’ and that was certainly not desired. Moving this propoerty back is not my prefered option at this stage.

The second issue is the impossibility to decrypt text encrypted with 5.1.0.3. I may have missed something, but here is a short code with NIST test vectors:

// The Advanced Encryption Standard Algorithm Validation Suite (AESAVS), November 15, 2002
//   AES 256-bit key:
MyAESEncryption.KeyLength := kl256;
MyAESEncryption.Key := #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0;
MyAESEncryption.IVmode := userdefined;
MyAESEncryption.IV  := #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0;
MyAESEncryption.paddingMode := noPadding;
MyText := #$01#$47#$30#$f8#$0a#$c6#$25#$fe#$84#$f0#$26#$c6#$0b#$fd#$54#$7d;
InText := '5c9d844ed46f9885085e5d6a4f94c7d7'; // correct output

MyAESEncryption.Unicode := noUni;
MainMemo.Lines.Add('256 bit key');

SW := TStopwatch.StartNew;
SW.Start;
OutText := MyAESEncryption.Encrypt(MyText);
MainMemo.Lines.Add('Expected cryptogram: ' + InText);
MainMemo.Lines.Add(OutText);

MyAESEncryption.OutputFormat := hexa;
OutText := MyAESEncryption.Decrypt(conv.FormatToChar(OutText));
MainMemo.Lines.Add(OutText);
Conv := TConvert.Create(hexa);
MainMemo.Lines.Add('Original text: ' + Conv.ToHexString(MyText));

The results are the following:

String encryption and decryption with the AES
256 bit key
Expected cryptogram: 5c9d844ed46f9885085e5d6a4f94c7d7
5C9D844ED46F9885085E5D6A4F94C7D7
014730F80AC625FE84F026C60BFD547D
Original text: 014730F80AC625FE1EF026C60BFD547D

Regards,

bernard

I use a simple process to encrypt/decrypt the texts.

To encrypt, I use the function:

Function TMenu_Sistema.Crypt_Text(Const pText: String): String;
Begin
   rmCrypt.InputFormat:=TConvertType.raw;
   rmCrypt.OutputFormat:=TConvertType.base64;
   Result:=rmCrypt.Encrypt(pText);
End;

To decrypt:

Function TMenu_Sistema.Decrypt_Text(Const pText: String): String;
Begin
   rmCrypt.InputFormat:=TConvertType.base64;
   rmCrypt.OutputFormat:=TConvertType.raw;
   Result:=rmCrypt.Decrypt(pText);
End;

rmCrypt is a TAESEncryption in the main form, and I set the key when the application starts:

procedure TMenu_Sistema.FormCreate(Sender: TObject);
Begin
  :
  :
  rmCrypt.Key:=c_Key; //String var with key
  :
  :
End;

Do you see anything in this code that might prevent texts encrypted with version 5.0.1.3 from being decrypted with version 5.1.1.0?

No, except for the KeyLength that may be set to a different default value between the two versions. Try to force it to kl256 with the new version, before setting c_key, to validate/invalidate this lead.

I had done that when I migrated to the new version, but it didn't solve the problem. That's why I reverted to the previous version.

I'll update again later and try to generate a test program to send you.

OK. If you could send me an example with exact values, that would help a lot. It may be that the IV is not set to the right format in one of the operations.

AESbug.zip (6.3 KB)

Attached is a project tested with 3 different versions and decrypting the initial string correctly.

Here is a project that demonstrates the problem.

I encrypted the letter A in version 5.1.0.3 and obtained the text:

Gz+ovv/712UqVNjI8pXqDfnAYRInriw23Q68zD0dqa4=

I decrypted this text in version 5.1.0.3 and obtained A again.

When decrypting this text in version 5.1.1.0, the result is null.

Crypt.zip (75.7 KB)

The same problem occurs in version 5.1.1.1.

Hi, you identified a bug in MiscObj.pas.

To make a long story short, I had to write a function to convert characters in unicode as the TEncoding class caused some issues.

Unfortunately the case where string length = 1 is not properly addressed.

To fix this issue, open up MiscObj.pas and go to TConvert.ToUtf8 (end of the file). At the end of the function, ca. line 2483, replace:

Result := t

by

if L = 1 then
Result := s
else
Result := t;

Let me know if this works (it does for me with ‘A’ as the input string) and I will issue a new version ASAP.

Regards,

bernard

Issue resolved.

Thank you.

Thanks for spotting this. I’ll issue a revised version.