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;