2

Im trying to make a crypt/decrypt routine using mcrypt but it seems to mess the data im trying to encrypt.

Heres the code:

    $data = 'Some important data';
    $key = "mycryptKey";
    $cipher = "rijndael-128";

    $encryptedData = mcrypt_encrypt($cipher, $key, $data, MCRYPT_MODE_ECB);
    $decryptedData = mcrypt_decrypt($cipher, $key, $encryptedData, MCRYPT_MODE_ECB);

    var_dump($data); //string 'Some important data' (length=19)
    var_dump($encryptedData); //string '™ì{*¾xv-&n5’Œü½Ýëc®n)mSƒ7]' (length=32)
    var_dump($decryptedData); //string 'Some important data�������������' (length=32)

It keeps adding those characters at the end of the original string. I saw an example at How do you Encrypt and Decrypt a PHP String? but it didn't work

Thats the actual test. The key and data I'm using are the same posted here

Edit

I realized, after @jonhopkins comment, that mcrypt was padding some "\0" characters after $data content, so i clean it up after decryption using 'strtok':

$decryptedData = \strtok( mcrypt_decrypt($cipher, $key, $encryptedData, MCRYPT_MODE_ECB), "\0" );
var_dump($decryptedData); //string 'Some important data' (length=19)
Community
  • 1
  • 1
CarlosCarucce
  • 3,420
  • 1
  • 28
  • 51
  • 2
    If I had to guess, I would guess that the encryption method is automatically padding the string. IIRC rijndael-128 requires its input to be of length that is a multiple of 16, so `mcrypt_encrypt` is padding with 0s up to 32 bytes, but I suppose `mcrypt_decrypt` is unable to determine the original length so it is leaving those extra bytes. – jonhopkins Feb 06 '15 at 03:34
  • You are a genius @jonhopkins! But heres another question: how im suposed to return the same data if i have to modify it before passing to mcrypt? – CarlosCarucce Feb 06 '15 at 03:50
  • That is a great question that I wish I knew the answer to... I'm not even 100% sure that's what's happening. But if I can find anything I'll let you know. edit: http://stackoverflow.com/q/20507050 this might help – jonhopkins Feb 06 '15 at 03:54
  • Got the answer: http://www.leaseweblabs.com/2014/02/aes-php-mcrypt-key-padding/ and updated my question. Thanks again @jonhopkins – CarlosCarucce Feb 06 '15 at 04:14
  • I will take a look later. Thanks for the tip @Ja͢ck – CarlosCarucce Feb 06 '15 at 04:17

1 Answers1

1

What you're missing here is the padding; the data to be encrypted must be padded first:

$data = pkcs7_pad($data, 16);

Likewise, after decryption you need to reverse the padding:

$decryptedData = pkcs7_unpad($decryptedData, 16);

Functions used:

function pkcs7_unpad($data)
{
    return substr($data, 0, -ord($data[strlen($data) - 1]));
}

function pkcs7_pad($data, $size)
{
    $length = $size - strlen($data) % $size;
    return $data . str_repeat(chr($length), $length);
}

Also, it's important to note that the mcrypt extension is rather old and not well maintained; I would recommend switching to OpenSSL instead. See my earlier answer for a full example.

Community
  • 1
  • 1
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309