1

I'm trying to rewrite this old code from C# to delphi 10.3 (using library lockbox 3.7). The output crypto are used for PHP script handling the DB running on the remote server, that PHP I cannot edit.

internal static string DecryptString_forPHP(string cipherText, byte[] key, byte[] iv)
        {
            string plainText = "";
            try
            {
                Aes encryptor = Aes.Create();
                encryptor.Mode = CipherMode.CBC;
                byte[] aesKey = new byte[32];
                Array.Copy(key, 0, aesKey, 0, 32);
                encryptor.Key = aesKey;
                encryptor.IV = iv;

                MemoryStream memoryStream = new MemoryStream();
                ICryptoTransform aesDecryptor = encryptor.CreateDecryptor();
                CryptoStream cryptoStream = new CryptoStream(memoryStream, aesDecryptor, CryptoStreamMode.Write);
                try
                {
                    byte[] cipherBytes = Convert.FromBase64String(cipherText);
                    cryptoStream.Write(cipherBytes, 0, cipherBytes.Length);
                    cryptoStream.FlushFinalBlock();
                    byte[] plainBytes = memoryStream.ToArray();
                    plainText = Encoding.UTF8.GetString(plainBytes, 0, plainBytes.Length);
                }
                finally
                {
                    memoryStream.Close();
                    cryptoStream.Close();
                }
            }
            catch (Exception e)
            {
                ErrorLog(1, System.Environment.NewLine + e.Message);
            }
            return plainText;
        }


internal static string EncryptString_forPHP(string plainText, byte[] key, byte[] iv)
        {
            string cipherText = "";
            try
            {
                Aes encryptor = Aes.Create();
                encryptor.Mode = CipherMode.CBC;
                byte[] aesKey = new byte[32];
                Array.Copy(key, 0, aesKey, 0, 32);
                encryptor.Key = aesKey;
                encryptor.IV = iv;
                MemoryStream memoryStream = new MemoryStream();
                ICryptoTransform aesEncryptor = encryptor.CreateEncryptor();
                CryptoStream cryptoStream = new CryptoStream(memoryStream, aesEncryptor, CryptoStreamMode.Write);
                byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
                cryptoStream.Write(plainBytes, 0, plainBytes.Length);
                cryptoStream.FlushFinalBlock();
                byte[] cipherBytes = memoryStream.ToArray();
                memoryStream.Close();
                cryptoStream.Close();
                cipherText = Convert.ToBase64String(cipherBytes, 0, cipherBytes.Length);
            }
            catch (Exception e)
            {
               ErrorLog(1, System.Environment.NewLine + e.Message);
            }
            return cipherText;
        }

Called for example with:

string password = "xxxxxxxxxxxxxxxxx";
                    // Create sha256 hash
                    SHA256 mySHA256 = SHA256Managed.Create();
                    byte[] key = mySHA256.ComputeHash(Encoding.UTF8.GetBytes(password));
                    // Create secret IV
                    byte[] iv = new byte[16] { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
                    string encrypted = EncryptString_forPHP(message, key, iv);
                    string decrypted = DecryptString_forPHP(message, key, iv);

I read and tried these, but always ended with different output then I expected or with some new error. How to use AES-256 encryption in lockbox 3 using delphi Turbopower Lockbox3 - Can I control initialization vector and padding for AES-256 encryption? LockBox 3 Encrypting not matching online tool, suspect padding or key problem Turbopower Lockbox3 - Can I control initialization vector and padding for AES-256 encryption?

This seems code for decrypt seems to me as most possible copy of the original C#, but the output is not equal. Is there problem with the used library (lockbox 3.7), version of delphi (10.3) or did I something simply overlook?

function DecryptAES256FromBase64String(const Value: String): String;
var
  Codec: TCodec;
  CryptographicLibrary: TCryptographicLibrary;
  CipherStream, PlainTextStream: TStream;
  buffer: array of Byte;
  mySHA256 : THashSHA2;
  key : TBytes;
begin
  Codec := TCodec.Create( nil);
  CryptographicLibrary := TCryptographicLibrary.Create(Codec);
  CipherStream := TMemoryStream.Create;
  PlainTextStream := TMemoryStream.Create;

  try
    Codec.CryptoLibrary := CryptographicLibrary;
    Codec.StreamCipherId := BlockCipher_ProgID;
    Codec.BlockCipherId := Format(AES_ProgId,[256]);
    Codec.AsymetricKeySizeInBits := 256;
    Codec.Cipher  := '[AES-256*]';
    Codec.ChainModeId := CBC_ProgId;

    mySHA256 := THashSHA2.Create();
    key := mySHA256.GetHashBytes(password, SHA256);

    CipherStream.WriteBuffer(key[0], Length(key));
    CipherStream.Position := 0;
    Codec.InitFromStream(CipherStream);
    CipherStream.Size := 0;
    CipherStream.WriteBuffer(IV[0], Length(IV));

    Base64_to_stream(TNetEncoding.Base64.DecodeStringToBytes(Value), CipherStream);
    CipherStream.Position := 0;
    Codec.DecryptStream(PlainTextStream, CipherStream);
    PlainTextStream.Position := 0;
    SetLength(buffer, PlainTextStream.Size);
    PlainTextStream.ReadBuffer(buffer[0], Length(buffer));
    Result := TNetEncoding.Base64.EncodeBytesToString(buffer);

  finally
    CipherStream.Free;
    PlainTextStream.Free;
    Codec.Free;
    CryptographicLibrary.Free;
  end;
end;
3
  • Hints: AES is not asymmetric and TCodec has a key property. The IV / nonce is written or retrieved from the stream automagically. Upgrading from C# to Delphi, oh well. Commented Mar 10, 2023 at 5:08
  • I might be a little late to the party, so maybe this comment won't be read. I have a few questions: (1) Is the encryptor under your control?; (2) Do you have control over the encryptor selection of IV?; (3) Is the encryptor LB3?; (4) Is the decryptor under your control?; (5) It appears that you are trying to write the decryptor in Delphi with LB3 but dont have control of the encryptor - please confirm; (6) Where did you source LB3? More questions to follow. Commented Mar 19, 2023 at 9:14
  • Please supply full test data. These include (1) Full ciphertext including IV as base64 string; (2) Is the IV tranported via a separate channel? or LockBox style as a ciphertext prepend? (3) The plaintext string; (4) The encoding of the plaintext (UTF-8 or UTF-16LE)? This last one may seem unimportant, but it is very important. Natively PHP is UTF-8. Natively Delphi is UTF-16LE.; (5) What is the key as a base64 string. (6) If the encryptor is not LB3, what padding scheme and block termination scheme does the encryptor use? (7) What library and language was used to encrypt? Commented Mar 19, 2023 at 9:20

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.