Skip to content

Different output form AES 256 PHP and Delphi FMX #31

Open

Description

@Morrismx

I have to encrypt/decrypt a string on AES 256 CBC, and I'm getting a shorter string compared wit PHP.

PHP Example:
https://gist.github.com/ezegg/8d54c98b8fbdce263409eabaf8afabe6

    PHP Output
   DB8BRqb2q6BW/HLQYN2pr2n9DTL1Q8kp2lvZi3rogbxjEasiMbgU4q5/vDav+p0O0KWlfMm
   NekXN+UkbUiB+s/LNf1MF2EgOQEZoivxgp+UJxsuT5vDIMmQXUkuwkyUE+a7hH5FwaDDY8D
   NwW2kowFXeE69AcOMaWnyZ+YplKNEUOzQzLstBxWnJE+aSr0+vQN3knkIIjbT10yfSTV/OQA==
  
  FMX Output.
   DB8BRqb2q6BW/HLQYN2pr2n9DTL1Q8kp2lvZi3rogbxjEasiMbgU4q5/vDav+p0O0KWlfMm
   NekXN+UkbUiB+s/LNf1MF2EgOQEZoivxgp+UJxsuT5vDIMmQXUkuwkyUE+a7hH5FwaDDY8D
   NwW2kowFXeE69AcOMaWnyZ+YplKNEUOzQzLstBxWnJE+aSr0+v9Q21xA==

As you can see, string is "shorter" in Delphi.

here is the test string, Secret key and init vector
SECRET_KEY = "HPo7OLqB4Fkk4E2yGOtwqw8H5fHR9kNx67OR4g4UdlA=";
IV = "p5ldmBPdd/9pjC0bDC/nSg==";

Input String:
{"idServicio":79, "idProducto":209 , "referencia": "40425475190118187271", "montoPago": 9999, "telefono":"1111111111", "horaLocal":"20200401222821"}

Thank you

Activity

  1. MHumm commented on Oct 26, 2021

    @MHumm
    Owner

    That should not differ. I have some suspicion...

    1. Could you please provide your Delphi source code?

    2. Did you call the Done method at the end before looking at the output?
      The Done method processes the last block (including padding where necessary)
      and could thus make the difference!

  2. Morrismx commented on Oct 26, 2021

    @Morrismx
    Author

    Hi,

    Im using Cipher_FMX demo proyect.

    procedure TFormMain.ButtonEncryptClick(Sender: TObject);
    var
    Cipher : TDECCipher;
    InputFormatting : TDECFormatClass;
    OutputFormatting : TDECFormatClass;
    InputBuffer : TBytes;
    OutputBuffer : TBytes;
    begin

    if not GetSettings(InputFormatting, OutputFormatting) then
    exit;

    if ComboBoxCipherAlgorithm.ItemIndex >= 0 then
    begin
    if not GetCipherAlgorithm(Cipher) then
    exit;

    try
      InputBuffer  := System.SysUtils.BytesOf(EditPlainText.Text);
    
      if InputFormatting.IsValid(InputBuffer) then
      begin
        OutputBuffer := (Cipher as TDECFormattedCipher).EncodeBytes(InputFormatting.Decode(InputBuffer));
        EditCipherText.Text := string(DECUtil.BytesToRawString(OutputFormatting.Encode(OutputBuffer)));
      end
      else
        ShowErrorMessage('Input has wrong format');
    finally
      Cipher.Free;
    end;
    

    end
    else
    ShowErrorMessage('No cipher algorithm selected');
    end;

    I not sure where should i call Done Method, i guess this method does the encryption:
    OutputBuffer := (Cipher as TDECFormattedCipher).EncodeBytes(InputFormatting.Decode(InputBuffer));

  3. MHumm commented on Oct 26, 2021

    @MHumm
    Owner

    Ok, done plays no role here as it seems. The answer was out of my head.
    But if I take the data you specify I get a key too long failure, the IV is not in hexadecimal etc.
    Is it possible to deliver the input data (include the filler byte used) in a form I can directly enter into the demo without any conversions etc.?

  4. Morrismx commented on Oct 26, 2021

    @Morrismx
    Author

    what i did for simplicity, was to convert IV to HEX and put the hex value on (a7995d9813dd77ff698c2d1b0c2fe74a ) on EditInitVector.text edit, and on GetCipherAlgorithm function I modified a bit. so I can decode the base64 secret key, as follows:

    function TFormMain.GetCipherAlgorithm(var Cipher : TDECCipher):Boolean;
    begin
    var SKey:RawByteString ;
    var i:integer;

    result := false;

    // Find the class type of the selected cipher class and create an instance of it
    Cipher := TDECCipher.ClassByName(
    ComboBoxCipherAlgorithm.Items[ComboBoxCipherAlgorithm.ItemIndex]).Create;

    if TFormat_HEX.IsValid(RawByteString(EditInitVector.Text)) and
    TFormat_HEX.IsValid(RawByteString(EditFiller.Text)) then
    begin
    if CheckBoxBase46.IsChecked then {Add this checkBox to decode Base64 secret key}
    begin
    SKey:=TFormat_Base64.Decode(EditKey.Text);
    Cipher.Init(Skey,
    TFormat_HEX.Decode(RawByteString(EditInitVector.Text)),
    StrToInt('0x' + EditFiller.Text));
    end else
    begin
    Cipher.Init(RawByteString(EditKey.Text),
    TFormat_HEX.Decode(RawByteString(EditInitVector.Text)),
    StrToInt('0x' + EditFiller.Text));

    end;
    Cipher.Mode := GetSelectedCipherMode;
    

    end
    else
    begin
    ShowErrorMessage('Init vector or filler byte not given in hexadecimal representation');
    exit;
    end;

    result := true;
    end;

  5. Morrismx commented on Oct 26, 2021

    @Morrismx
    Author

    here is the modified project.
    Cipher_FMX.zip

  6. MHumm commented on Oct 27, 2021

    @MHumm
    Owner

    Thanks for providing the modified project. I try to look at it as soon as I can, but currently there's too much going on, like finalizing the new release and preparing my talk on EKON (https://entwickler-konferenz.de/tips-tricks-and-technics/kryptographiegrundlagen-am-beispiel-der-dec-delphi-encryption-compendium/).

    The problem most likely has to do with the way DEC handles padding, which I'm not really familiar with yet. That was designed by the original creator of the library, which I do not know personally. I know his successor though, but I doubt he did much on that part.

  7. MHumm commented on Oct 28, 2021

    @MHumm
    Owner

    Somebody (not me due to lack of time) tried to run yet test program provided but got an exception. The key length is too long. Is the key base 64 coded?

  8. fastbike commented on May 5, 2022

    @fastbike

    The implementation of TNetEncoding Base64 in Delphi has a built in limit at which point it splits with a CRLF sequence - not sure if this is helpful ? We had an issue with a truncated encrypted value due to this.

  9. MHumm commented on May 5, 2022

    @MHumm
    Owner

    Thanks for adding the idea it might be related to line break handling in Delphi's Base64 implementation.
    @Morrismx can you check that one?
    DEC contains its own Base64 implementation in DECFormat.pas unit, if I'm not mistaken that one has a property to set the line width. But I'm right now a bit in a hurry, so I cannot check the code :-(

  10. geoffsmith82 commented on Oct 9, 2022

    @geoffsmith82

    @fastbike FYI If you manually create a TBase64Encoding instead of of using TNetEncoding.Base64... you can specify line length, including not splitting it up on a line at all.

    Also I have noticed in my 11.2 that there actually is a TNetEncoding.Base64String that doesn't split the base64 up into lines at all.

  11. MHumm commented on Oct 9, 2022

    @MHumm
    Owner

    Can somebody of you check if that splitting is the culprit?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions