Reputation: 6465
I need to encrypt an 10-byte string in Delphi using 3DES.
It must get the same result than this PHP code:
function encrypt_3DES($message, $key){
$bytes = array(0,0,0,0,0,0,0,0);
$iv = implode(array_map("chr", $bytes));
$ciphertext = mcrypt_encrypt(MCRYPT_3DES, $key, $message, MCRYPT_MODE_CBC, $iv);
return $ciphertext;
I have been trying to code it using DCPCrypt and LockBox 3. I have finally discarded DCPCrypt because it hasn't been update lately and I'm not sure if it works correctly with Delphi 10.1 Berlin, so I have focused in LockBox 3, but I haven't been able to get the encryption right.
The encryption key is a 24bytes key (which I have its base64 representation). I can't find how to create such key using the TSymetricKey class of LockBox to pass it to an Codec.Init method. So I put it on an AnsiString and set it on the Password property (although the documentations says that there is a utf8Password but I can't find it).
Then there is a method called EncryptAnsiString, but again it expects strings (utf16 on Delphi 10.1 Berlin) instead of AnsiStrings (although the documentation says the contrary), so I'm not surprised that the result doesn't match what I'm looking for (the same value encrypted on that PHP snippet).
This is my Delphi Code :
function Encrypt(Data: AnsiString; LocalKey: AnsiString): AnsiString;
var
BinaryLocalKey: TBytes;
strLocalKey, strTripleDes: AnsiString;
begin
BinaryLocalKey := DecodeBase64(LocalKey);
setString(strLocalKey, PAnsiChar(@BinaryLocalKey[0]), Length(BinaryLocalKey));
Codec1.Rest;
Codec1.Password := strLocalKey;
Codec1.EncryptAnsiString(Data, strTripleDES);
Codec1.Reset;
Result := strTripleDes;
end;
But this Code not only doesn't get the same result as the PHP code, but at every call it returns a different result for the same input.
NOTE: Codec1 is a component linked to a TCryptographicLibrary component, and with the propertis ChainMode set to CBC* and Cipher set to 3DES (Keying option 1)
Does somebody know how to properly get this 3DES encryption ?.
Thank you.
Upvotes: 3
Views: 2190
Reputation: 12729
A random IV is generated for each message. The low 8 bytes of the IV are a nonce and the high bytes are zero. These low 8 bytes are prepended to the output.
If you want to send the IV via a side channel, then strip the first 8 bytes out of the nominal ciphertext.
If you want to control the IV, then use version 3.7.0 (https://github.com/SeanBDurkin/tplockbox). You will need to set the advanced options and implement the OnGetIV method.
The asterisk (*) rendered in the property editors for cipher selection and chain mode selection, mean that this selection is a recommended one.
Upvotes: 1