#1 2020-01-27 15:05:12

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 332

Compatibility problem between AESCBC 256 mORMot and C#

I need to generate a key using AES CBC 256 PKCS7 encryption for a .Net C# application that use this key for password when connection to database. The key have the form IV.KEY and is stored in a config file. I have the following code to generate the key in that way.

var
  lKey: TBytes;
  lIV: TAESBlock;
  lText, lTextEncrypted, lIVText: RawByteString;
  lAESCBC: TAESCBC;
begin
  ...
      // edtKey.Text is KEY
      // edtSource.Text is TEXT TO ENCRYPT
      SetLength(lKey, Length(edtKey.Text));
      SynCommons.HexToBin(Pointer(edtKey.Text), @lKey, Min(Length(edtKey.Text),SizeOf(lKey)));
      RawByteStringToBytes(RawByteString(edtKey.Text), lKey);
      lAESCBC := TAESCBC.Create(lKey, CRYPT_KEY_SIZES[2]{=256});
      try
        lText := StringToUTF8(edtSource.Text);
        TAESPRNG.Main.FillRandom(lIV);
        lAESCBC.IV := lIV;
        lTextEncrypted := SynCommons.BinToBase64(lAESCBC.EncryptPKCS7(lText));
        lIVText := SynCommons.BinToBase64(@lAESCBC.IV, SizeOf(lAESCBC.IV));
        edtDest.Text := UTF8ToString(lTextEncrypted)+'.'+lIVText;
      finally
        lAESCBC.Free;
      end;
  ...
end;

and the key generated with the above code

KEY=key
TEXT TO ENCRYPT=text to encrypt

oTfXA3+lm6aiOaGYjCsk+Q==.OX0qIq1iSEMhTdw/fl0ehg== (the dot is a separator)

raise an exception <b>Padding is invalid and cannot be removed.</b>

For testing I'm using dotfiddle.net in https://dotnetfiddle.net/tlO25C

What's wrong ?

Thanks.


Esteban

Offline

#2 2020-01-28 13:29:35

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 332

Re: Compatibility problem between AESCBC 256 mORMot and C#

The text <b>pepego</b> with key <b>Aesdns06</b> works ok in https://dotnetfiddle.net/tlO25C and was generated with a C# application.

Any idea why mORMot encryption not working ?

Thanks.


Esteban

Offline

#3 2020-01-28 14:03:52

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 13,048
Website

Re: Compatibility problem between AESCBC 256 mORMot and C#

Both code are not equivalent.

For instance, at first glance, the DotNetFiddle version is padding the key UTF-8 with zeros up to the key size of 256 bits, whereas you are calling TAESCBC.Create(const aKey; aKeySize: cardinal) which is pretty much incorrect because you are hashing the lKey pointer on stack, not the bytes themselves.

Padding UTF-8 with zeros is weak for sure. I wouldn't use this C# code as reference.
Use a proven password hashing method like TAESCBC.CreateFromPBKDF2() using PBKDF2_HMAC_SHA256.

Offline

#4 2020-01-28 14:45:26

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 332

Re: Compatibility problem between AESCBC 256 mORMot and C#

Thanks @ab, I'll try that the provider modify the algorithm, but in case that's not posible, how use TAESCBC to make the encryption as in C# ?.

Thanks again.


Esteban

Offline

#5 2020-03-06 20:45:19

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 332

Re: Compatibility problem between AESCBC 256 mORMot and C#

Hi @ab, I found the problem the compatibility (or not perhaps is by design):

in:

constructor TAESAbstract.Create(const aKey; aKeySize: cardinal);
begin
   if (aKeySize<>128) and (aKeySize<>192) and (aKeySize<>256) then
    raise ESynCrypto.CreateUTF8('%.Create(aKeySize=%): 128/192/256 required',[self,aKeySize]);
  fKeySize := aKeySize;
  fKeySizeBytes := fKeySize shr 3;
  MoveFast(aKey,fKey,fKeySizeBytes); <<<--- (1)
end;

(1) if the key is, for example, "12345678" the byte array TAESKey should be:

[49, 50, 51, 52, 53, 54, 55, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

in other words, the rest of array should be completed with zeroes but is filled with other values that are valids. For workaround I added Key as property in TAESAbstract with read/write and after create I refilling with correct data and it works.

Can you tell me if this behavior is by design or bug ?

UPDATE:
I removed Key property from TAESAbstract and implemented TAESAbstrackHack for accessing fKey protected member.
I don't know how patch MoveFast for non-filling with invalid values the rest of byte array. I think that Create constructor should have extra parameter with length of key text.

Thanks.

Last edited by EMartin (2020-03-07 15:56:42)


Esteban

Offline

#6 2020-03-07 16:09:11

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 13,048
Website

Re: Compatibility problem between AESCBC 256 mORMot and C#

Having less than aKeySize bits in aKey when calling TAESAbstract.Create() is clearly a problem of misuse on your side.
All calls of TAESAbstract.Create() in the framework define all needed bits.

The key is expected to be of the specified size, not less. There is no way of Create() to know how much data is really in aKey: it is just a pointer.
If you need some key padding, do it before calling.
So your code is to be fixed.

Offline

#7 2020-03-07 17:24:12

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 332

Re: Compatibility problem between AESCBC 256 mORMot and C#

You mean that the text key always should be of 32 characteres ?


Esteban

Offline

#8 2020-03-07 17:51:22

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 13,048
Website

Re: Compatibility problem between AESCBC 256 mORMot and C#

Use a THash128 THash192 or THash256.
Not a string.
It is unsafe not to use all bits. Hash the string.

Offline

Board footer

Powered by FluxBB