Reputation: 6798
I use the following function to decrypt data on my server:
function decrypt($key, $text) {
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)));
}
I have read a lot about NOT using ECB however (and know it is deprecated so wanted to switch to CBC. Simply switching the mode to:
function decrypt($key, $text) {
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($text), MCRYPT_MODE_CBC, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND)));
}
does not work however. No errors are generated but the data returned is still encrypted.
What am I missing?
$key = "hello";
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM);
function encrypt($key, $text) {
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv)));
}
function decrypt($key, $text) {
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($text), MCRYPT_MODE_CBC, $iv));
}
$text = 12345;
echo "Plain Number : " . $text . "<br><br>";
$encrypted = encrypt($key, $text);
echo "AES Number : " . $encrypted . "<br><br>";
echo "Plain Number : ". decrypt($key, $encrypted) . "<br><br>";
this should work - but it returns the error:
blocksize in
blocksize in> Warning: mcrypt_encrypt()
[function.mcrypt-encrypt]: The IV parameter must be as long as the blocksize inblocksize in
blocksize in
Upvotes: 5
Views: 14491
Reputation: 83672
Your updated code has an issue with $iv
being a global variable that's not available in the respective en-/decoding functions:
$key = "hello";
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM);
function encrypt($key, $text, $iv) {
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv)));
}
function decrypt($key, $text, $iv) {
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($text), MCRYPT_MODE_CBC, $iv));
}
$text = 12345;
echo "Plain Number : " . $text . "<br><br>";
$encrypted = encrypt($key, $text, $iv);
echo "AES Number : " . $encrypted . "<br><br>";
echo "Plain Number : ". decrypt($key, $encrypted, $iv) . "<br><br>";
Or you can still rely on the global $iv
by importing it into the local function scope:
function encrypt($key, $text) {
global $iv; // or use $GLOBALS['iv] instead of $iv in the call below
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv)));
}
function decrypt($key, $text) {
global $iv; // or use $GLOBALS['iv] instead of $iv in the call below
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($text), MCRYPT_MODE_CBC, $iv));
}
but this is surely not a recommended practice as it couples your code to global variables.
Upvotes: 5
Reputation: 52372
Did you change the mode when encrypting this text as well?
Also, when using MCRYPT_MODE_CBC, you need to use the same key and IV during encryption and decryption. Randomized IV does not work with CBC.
Upvotes: 3
Reputation: 54516
When you decrypt you need to use the same IV as when you encrypted. It looks like you're generating a new, random IV during decryption.
It's OK to append or prepend the IV to the ciphertext. IVs are not secret but they should be unique for each encrypted message and only used once.
Upvotes: 7