Question

I have 2 encrypt & decrypt functions using PHP mcrypt library.

public function encrypt_string($input, $key) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $cipher = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $input, MCRYPT_MODE_CBC, $iv);
    return base64_encode($iv . $cipher);
}
public function decrypt_string($input, $key) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $ciphertext = base64_decode($input);
    $iv = substr($ciphertext, 0, $iv_size);
    $cipher = substr($ciphertext, $iv_size);
    return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $cipher, MCRYPT_MODE_CBC, $iv);
}

Given that the key is generated by:

$key = pack('H*', 'dfgsdighsdfksdhfosdfasdjldsfsdfgdfkgdl'); // a random key

I can successfully obtain back the input after encryption & decryption.

Here is the code:

$pass = '123456';
echo sha1($pass) . PHP_EOL; // prints 7c4a8d09ca3762af61e59520943dc26494f8941b
$pass_cipher = encrypt_string($pass, $key);
$pass_decrypt = decrypt_string($pass_cipher, $key);
echo $pass_decrypt . PHP_EOL; // prints 123456
echo sha1($pass_decrypt) . PHP_EOL; // prints f41b44dbecccaccfbb4ccf6a7fc4921c03878c6d

However, the SHA1 result is different:

7c4a8d09ca3762af61e59520943dc26494f8941b // before encrypt & decrypt
f41b44dbecccaccfbb4ccf6a7fc4921c03878c6d // after encrypt & decrypt

Why is it different ? What did I miss ?

UPDATE:

The accepted answer is useful. For people who wants additional information, here it is:

echo bin2hex($pass) . PHP_EOL; // prints 313233343536
echo bin2hex($pass_decrypt) . PHP_EOL; // prints 31323334353600000000000000000000

and after trim(), the SHA1 result works as expected, as empty hidden 0 are removed.

Was it helpful?

Solution

Problem is that your decrypt_string returns 16 bytes string, that is filled with 0 bytes at the right side. It's a problem known for about 2 years.

Remove null bytes from the right with line similar to this one:

return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $cipher, MCRYPT_MODE_CBC, $iv), "\0");

Be careful not to encrypt things with null character at the end, as cryptology functions in PHP works as if all strings were null-terminated and are not shy to cut string at first \0 or to return a bit of \0s glued to the end of their output.

OTHER TIPS

in post encrypted data + sign will be replaced with whitespace. thats why decryption was not done .

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top