I've been wrestling with decrypting a given string, generated by a remote ColdFusion server, in PHP using AES in CBC mode with PKCS5 padding. I've gotten to the point where I can decrypt the string almost perfectly, the issue is there appears to be some cruft at the beginning of the string. I thought padding happened at the end, but looking at the decrypted string, there's nothing at the end, but the beginning is padded out so the string is 64 characters long (the original string is 32 characters long.) I attempted to switch my padding removal code to look at the beginning instead of the end, but those characters don't provide any information I can use to decipher how much padding to remove, so I think they are coming from somewhere else. Here's my code so far
function decrypt($hash) {
$enc_key = "Oq2vh+gswPn2CRPccODtKg==";
$cipher = "rijndael-128";
$str = mcrypt_decrypt($cipher, base64_decode($enc_key), base64_decode($hash), MCRYPT_MODE_CBC);
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$pad = ord($str[($len = strlen($str)) - 1]);
$len = strlen($str);
$decrypted = substr($str, 0, strlen($str) - $pad);
if($decrypted != NULL) {
$params = explode ('|', $decrypted);
}
return (object)array(
'input' => $hash,
'pad' => $pad,
'len' => $len,
'blocksize' => $block,
'aes_key' => $enc_key,
'cipher' => $cipher,
'result' => $params,
'decrypted' => $decrypted,
'padded' => $str
);
If I encrypt the string (using ColdFusion, '"AES/CBC/PKCS5Padding"' algorithm and base64 encoding):
"test@example.com|test|1400863515"
I get the encrypted string:
QRO04vmtw76Qvl0hscmYZ/SFGNv/8d88H9kT60JA5IJdg/KMT7udrn2IZuQzkOPvLjXoc4novzTMGsk0CMxjvg==
and when I run this through the above PHP function, I get this as output:
¹¾Sò'->äe¿fÏäJ±test@example.com|test|1400863515
What are those characters at the beginning? Why is there no padding at the end? I've read through dozens of posts on SO and elsewhere (which is how I got this far) but this last piece has me scratching my head.
(From comments ...)
CBC mode requires an
iv
. "Decrypting with the incorrect IV causes the first block of plaintext to be corrupt ...". Try using the sameiv
on both sides