Search code examples
phpencryptionmcrypt

mcrypt messing with data


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)

Solution

  • 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.