I have a trouble with lockbox3 and PHP mcrypt. I can’t pass IV to PHP. Delphi code:
var
Codec: TCodec;
CL: TCryptographicLibrary;
PlainStream: TStringStream;
CipherStream: TMemoryStream;
begin
PlainStream := TStringStream.Create(Edit1.Text);
CipherStream := TMemoryStream.Create;
CL := TCryptographicLibrary.Create(nil);
Codec := TCodec.Create(nil);
Codec.CryptoLibrary := CL;
Codec.ChainModeId := uTPLb_Constants.CBC_ProgId;
Codec.StreamCipherId := uTPLb_Constants.BlockCipher_ProgId;
Codec.BlockCipherId := Format(uTPLb_Constants.AES_ProgId, [256]);
Codec.Password := Edit3.Text;
Codec.EncryptStream(PlainStream, CipherStream);
Codec.Burn;
Memo1.Text := Stream_to_Base64(CipherStream);
Memo2.Clear;
Memo2.Lines.Add(Format('Size: %d bytes', [CipherStream.Size]));
Memo2.Lines.Add(Format('Original size: %d bytes', [PlainStream.Size]));
Codec.Free;
CL.Free;
CipherStream.Free;
PlainStream.Free;
And PHP code:
$ciphertext = base64_decode("zA/eeF+WFVMDsZ7+iA==");
$iv = substr($ciphertext, 0, 8);
$text = substr($ciphertext, 8, strlen($ciphertext) - 8);
$td = mcrypt_module_open("rijndael-256", "", "cbc", $iv);
mcrypt_generic_init($td, "PasswordPassword", $iv);
$plaintext = mdecrypt_generic($td, $text);
echo $plaintext;
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
I got an error:
Warning: mcrypt_generic_init() [function.mcrypt-generic-init]: Iv size incorrect; supplied length: 8, needed: 32 in C:…\aestest.php on line 7
Related thread: AES Encrypt/Decrypt Delphi & PHP
You haven’t said what version of Delphi you are using. This is an important detail. For the moment, I will assume it is Delphi 2010. There are a number of problems with your code. I will address them…
(1) In Delphi 2010 and later, strings are encoded in UTF-16LE, whilst in PHP, strings are UTF-8. Consider this line of yours…
What you are doing is creating the UTF-16LE encoding of your payload string. You encrypt this and pass it over to the PHP side and decrypt it. But you are not going to get the expected result because the decrypted bytes are UTF-16LE, but PHP expects them to be UTF-8.
(2) TP Lockbox 3 already had native methods for encrypting strings. Why not use them?
(3) The block size for all 3 variations of AES is 128 bits, which is 16 bytes. The size of the IV is always the size of the block. On the PHP side, as a matter of generic coding, you should always call mcrypt_enc_get_iv_size() (you did not). Please read the reference page here. In any case, for AES-256 must return 16 bytes. If not something is seriously wrong.
(4) Your passwords are not the same, so you can never reasonably expect a happy result. On the Delphi side, your password is encoded in UTF-16LE. On the PHP side, your password is the UTF-8 encoding of ‘PasswordPassword’, which can never be byte-for-byte equal to something valid in UTF-16.
(5) On the PHP side, you wrote..
You need to zero-extend this out to 16 bytes. Refer to this question.
UPDATE
As promised, here is some PHP code to decrypt ciphertext messages produced by TurboPower LockBox 3. You will need to craft a css file, otherwise presentation will be ugly.
… and here is a matching Delphi program to produce the ciphertext messages for the preceding PHP web page, for test and demonstration purposes. (DFM file not included)…