Search code examples
phpmysqldelphiaesmcrypt

AES crypt Delphi/PHP corrupted output


I encrypt some data in Delphi and send it via GET to PHP script which decrypts it and adds result to MySQL database. The problem is it sometimes adds one "�" or more "���" at the end of data. Here is the code:

const
  URL = 'http://127.0.0.1/script.php?data=';
  PACK_SEPARATOR = '|';
  KeySize = 32;
  BlockSize = 16;

function aes_encrypt(const Data: string; const Key: string; const IV: string) : string;
var
  Cipher : TDCP_rijndael;
  tempData, tempKey, tempIV : string;
begin
  tempKey := PadWithZeros(Key,KeySize);
  tempIV := PadWithZeros(IV,BlockSize);
  tempData := PadWithZeros(Data,BlockSize);
  Cipher := TDCP_rijndael.Create(nil);
  if Length(Key) <= 16 then
    Cipher.Init(tempKey[1],128,@tempIV[1])
  else if Length(Key) <= 24 then
    Cipher.Init(tempKey[1],192,@tempIV[1])
  else
    Cipher.Init(tempKey[1],256,@tempIV[1]);
  Cipher.EncryptCBC(tempData[1],tempData[1],Length(tempData));
  Cipher.Free;
  FillChar(tempKey[1],Length(tempKey),0);
  Result := Base64EncodeStr(tempData);
end;


function PadWithZeros(const str : string; size : integer) : string;
var
  origsize, i : integer;
begin
  Result := str;
  origsize := Length(Result);
  if ((origsize mod size) <> 0) or (origsize = 0) then
  begin
    SetLength(Result,((origsize div size)+1)*size);
    for i := origsize+1 to Length(Result) do
      Result[i] := #0;
  end;
end;

function HTTPEncode(const AStr: String): String;
const
  NoConversion = ['A'..'Z','a'..'z','*','@','.','_','-'];
var
  Sp, Rp: PChar;
begin
  SetLength(Result, Length(AStr) * 3);
  Sp := PChar(AStr);
  Rp := PChar(Result);
  while Sp^ <> #0 do
  begin
    if Sp^ in NoConversion then
      Rp^ := Sp^
    else
      if Sp^ = ' ' then
        Rp^ := '+'
      else
      begin
        FormatBuf(Rp^, 3, '%%%.2x', 6, [Ord(Sp^)]);
        Inc(Rp,2);
      end;
    Inc(Rp);
    Inc(Sp);
  end;
  SetLength(Result, Rp - PChar(Result));
end;


packedData := Memo1.Lines.Text + PACK_SEPARATOR + Edit1.Text + PACK_SEPARATOR + Edit2.Text;
encryptedData := aes_encrypt(packedData, KEY, IV);
encryptedData := HTTPEncode(encryptedData);
serverMsg := DownloadFile(URL+encryptedData);

'packedData' length before encryption is about 133. After encryption about 200 so it isn't break some servers GET data limit.

Now PHP code:

function aes_decrypt($dataToDecrypt, $key, $iv)
{
    $decoded = base64_decode($dataToDecrypt);
    $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $decoded, MCRYPT_MODE_CBC, $iv);
    return $decrypted;
}

$packedData = aes_decrypt($_GET['data'], KEY, IV);
$unpacked = explode(PACK_SEPARATOR, $packedData);
$smth1 = $unpacked[0];
$smth2 = $unpacked[1];
$smth3 = $unpacked[2];
$params = array(':thing' => $somevar, ':data1' => $smth1, ':data2' => $smth2, ':data3' => $smth3);
$query = $pdo->prepare('UPDATE one_table SET somedata1 = :data1 , somedata2 = :data2 , somedata3 = :data3 WHERE something = :thing LIMIT 1'); 
$success = $query->execute($params);

I spend really many hours trying to resolve this problem. Some time ago I had problems with encrypted PHP output with binary data, the problem was aes_decrypt function so I changed it into you can see above. Right now I don't know where is the problem. Delphi encrypt, PHP decrypt or in sending data via GET? Thank you for any help you are able to provide.


Solution

  • Looks like a encoding problem with diffrent character sets. Check the character sets you use in delphi and php. I can imagine that your strings are latin-1 in delphi and UTF-8 in php. And because of that some strange symbols appears.