Seems that mcrypt_decrypt
can't proper decrypt my string (all works fine in var_dump
except when decrypting - load_decrypted
value is wrong). Any help would be appreciated.
array
'salve_plain' => string 'a:1:{s:8:"modified";i:1321974656;}' (length=34)
'save_encrypted' => string '^ånÄc¥JŸRæk®»}J%áR–y #‡nwZX\µÚ™È§œ‘5‚<_¹M¿ÔT9k)…ª Ø' (length=64)
'save_encoded' => string 'XuVuxGOlA0qfUuYXa667fUoSEyXhBVKWeSAjh253EFpYXLUS2pnIp5yRNa3LgjxfuRNNv9RUOe67qmsphaoJ2A==' (length=88)
array
'load_undecoded' => string 'XuVuxGOlA0qfUuYXa667fUoSEyXhBVKWeSAjh253EFpYXLUS2pnIp5yRNa3LgjxfuRNNv9RUOe67qmsphaoJ2A==' (length=88)
'load_decoded' => string '^ånÄc¥JŸRæk®»}J%áR–y #‡nwZX\µÚ™È§œ‘5‚<_¹M¿ÔT9k)…ª Ø' (length=64)
'load_decrypted' => string '-dœÞ{*€ ¥ûü(1À�ðú-›(!*»ÓÍW¦;}' (length=34)
PHP load()
function:
private function load()
{
// Decoding
$plain = file_get_contents($this->filename);
$decoded = base64_decode($plain);
// Decrypting
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($this->secret),
$decoded, MCRYPT_MODE_CBC, $iv));
// Deserializing & loading
$this->data = unserialize($decrypted);
var_dump(array('load_undecoded' => $plain, 'load_decoded' => $decoded,
'load_decrypted' => $decrypted));
}
PHP save()
function:
private function save()
{
// Serialization
$serialized = serialize($this->data);
// Encrypting
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($this->secret),
$serialized, MCRYPT_MODE_CBC, $iv);
// Encoding & saving
$encoded = base64_encode($encrypted);
file_put_contents($this->filename, $encoded);
var_dump(array('salve_plain' => $serialized,
'save_encrypted' => $encrypted, 'save_encoded' => $encoded));
}
Unfortunately you need the same $iv in both the load and the save.
// Creates a random value so that the same message encoded with the same key
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
A way around it is to use
$mode = MCRYPT_MODE_CFB;
Encrypt with
$encrypted = mcrypt_encrypt($cipher, $key, $iv . $message, $mode, $iv);
Prefix the encoded message with the IV, and then in decoding use
$decrypted = mcrypt_decrypt($cipher, $key, $encrypted, $mode, str_pad('', $iv_size));
$decrypted = substr(rtrim($decrypted, "\0"), $iv_size);
CFB has the ability to re-sync during decryption, and can use this 'recovery' feature to put your IV in.
Also, depending on the number of IVs you're creating, you may want to use urandom rather then random.
$iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM);