I'm trying to encrypt some data using the MCRYPT_RIJNDAEL_128 algoritm. But somehow when I encrypt and afterwards decrypt, the decrypted data has randomly added bytes.
The input: string(13) "test@test.com"
The output: string(16) "test@test.com"
As you can see the output has 16 characters while the input has 13.
The following is the code used for encryption.
class Cipher
{
/**
* The key/salt(bin2hex format) used to encrypt data with in AES(RIJNDAEL) format.
* @var string
*/
private static $encryptionKey = 'baafbd1f8d752d920caae00ae550be8185c1183207a142c97c36fca3edc507da';
/**
* Gets and transforms the encryption key to binary format.
* @return string (in binary format)
*/
public static function getEncryptionKey()
{
return hex2bin(self::$encryptionKey);
}
/**
* Generates a new random main encryption key used to encrypt data.
* Store the generated key in the private property of this class.
* @param bool $strong Whether the encryption will be strong.
* @return string The generated key in hexadecimal format.
*/
public static function generateEncryptionKey($strong = true)
{
$keySize = mcrypt_get_key_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
return bin2hex(openssl_random_pseudo_bytes($keySize, $strong));
}
/**
* Creates an encryption key IV used to store near the database record for the encrypted data.
* Use bin2hex function for a representational string.
* @return string (in binary format)
*/
public static function createIv()
{
$ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
return mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM);
}
/**
* Encrypts a given string by the generated encryption key and generated IV.
* @param string $string The string which will be encrypted.
* @param string $iv The dynamic key used to encrypt.
* @return string (in binary format)
*/
public static function encrypt($string, $iv)
{
return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, self::getEncryptionKey(), $string, MCRYPT_MODE_CBC, $iv);
}
/**
* Decrypts a given string by the generated encryption key and generated IV.
* @param string $string The binary string which will be decrypted.
* @param string $iv The dynamic key which belongs to the encrypted string.
* @return string The decrypted string.
*/
public static function decrypt($string, $iv)
{
return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, self::getEncryptionKey(), $string, MCRYPT_MODE_CBC, $iv);
}
}
The encryption key showed here isn't used in production or testing environments and is only used for display purposes.
The following is used to display the decryption
$iv = Cipher::createIv();
$emailAddress = Cipher::encrypt('test@test.com', $iv);
var_dump(Cipher::decrypt($emailAddress, $iv));exit;
I'm using the following environments:
Ubuntu: 14.10
PHP: PHP 5.5.9-1ubuntu4.3 (cli) (built: Jul 7 2014 16:36:58)
Those are just padding 0x00 characters added at the end, because the string's length for that cryptographic algorithms has to be a multiple of 16 (with 128 bit).
Indeed, if you add at the end of your code:
var_dump(bin2hex(Cipher::decrypt($emailAddress, $iv)));
You can see that the last 6 characters are all 0's (which means there are 3 0x00 bytes at the end).
To remove them, just run:
$decrypted = rtrim($decrypted, "\0");