I have a code that goes something like:
$cipher_alg = MCRYPT_RIJNDAEL_128;
$decrypted_string = mcrypt_decrypt($cipher_alg, $key,
$encrypted_string , MCRYPT_MODE_CBC, trim(hex2bin(trim($hexiv))));
I worry that in the process of decoding the mcrypt_decrypt
will introduce a gratuitous whitespace or null characters at the back or front of the $decrypted_string
.
So should I trim it?
Note: I could have run the code and find this out. But since I can never run enough samples to prove ( or disprove) my point, I want some concrete and theoretical answers, probably based on the inner working of the mcrypt_decrypt
algorithm. Another reason I ask is that I believe this is going to help others.
Note 2: Notwithstanding with the answer below ( now deleted and only 10K users can see it), it seems that the examples here do use trimming to get the correct decrypted string.
Actually both mcrypt_encrypt()
and mcrypt_decrypt()
as well as the other en-/decryption functons (like mcrypt_generic()
or mdecrypt_generic()
) do pad the $data
parameter to a length of n * <<blocksize>>
. The padding character is the NUL
character (\x0
or \0
) whereas the <<blocksize>>
depends on the cipher and the block cipher modes used. You should have a look at Block cipher modes of operation and Padding (cryptography).
The following is the output of mcrypt_get_block_size()
for each of the available ciphers and modes on my machine. Obviously the function does not take into account that modes such as CFB, OFB and CTR do not require any special measures to handle messages whose lengths are not multiples of the block size, since they all work by XORing the plaintext with the output of the block cipher (quote from Wikipedia). CBC which is used in your example always requires that the final block is padded before encryption.
cast-128
cbc: 8 bytes
cfb: 8 bytes
ctr: 8 bytes
ecb: 8 bytes
ncfb: 8 bytes
nofb: 8 bytes
ofb: 8 bytes
stream: not supported
gost
cbc: 8 bytes
cfb: 8 bytes
ctr: 8 bytes
ecb: 8 bytes
ncfb: 8 bytes
nofb: 8 bytes
ofb: 8 bytes
stream: not supported
rijndael-128
cbc: 16 bytes
cfb: 16 bytes
ctr: 16 bytes
ecb: 16 bytes
ncfb: 16 bytes
nofb: 16 bytes
ofb: 16 bytes
stream: not supported
twofish
cbc: 16 bytes
cfb: 16 bytes
ctr: 16 bytes
ecb: 16 bytes
ncfb: 16 bytes
nofb: 16 bytes
ofb: 16 bytes
stream: not supported
arcfour
cbc: not supported
cfb: not supported
ctr: not supported
ecb: not supported
ncfb: not supported
nofb: not supported
ofb: not supported
stream: 1 bytes
cast-256
cbc: 16 bytes
cfb: 16 bytes
ctr: 16 bytes
ecb: 16 bytes
ncfb: 16 bytes
nofb: 16 bytes
ofb: 16 bytes
stream: not supported
loki97
cbc: 16 bytes
cfb: 16 bytes
ctr: 16 bytes
ecb: 16 bytes
ncfb: 16 bytes
nofb: 16 bytes
ofb: 16 bytes
stream: not supported
rijndael-192
cbc: 24 bytes
cfb: 24 bytes
ctr: 24 bytes
ecb: 24 bytes
ncfb: 24 bytes
nofb: 24 bytes
ofb: 24 bytes
stream: not supported
saferplus
cbc: 16 bytes
cfb: 16 bytes
ctr: 16 bytes
ecb: 16 bytes
ncfb: 16 bytes
nofb: 16 bytes
ofb: 16 bytes
stream: not supported
wake
cbc: not supported
cfb: not supported
ctr: not supported
ecb: not supported
ncfb: not supported
nofb: not supported
ofb: not supported
stream: 1 bytes
blowfish-compat
cbc: 8 bytes
cfb: 8 bytes
ctr: 8 bytes
ecb: 8 bytes
ncfb: 8 bytes
nofb: 8 bytes
ofb: 8 bytes
stream: not supported
des
cbc: 8 bytes
cfb: 8 bytes
ctr: 8 bytes
ecb: 8 bytes
ncfb: 8 bytes
nofb: 8 bytes
ofb: 8 bytes
stream: not supported
rijndael-256
cbc: 32 bytes
cfb: 32 bytes
ctr: 32 bytes
ecb: 32 bytes
ncfb: 32 bytes
nofb: 32 bytes
ofb: 32 bytes
stream: not supported
serpent
cbc: 16 bytes
cfb: 16 bytes
ctr: 16 bytes
ecb: 16 bytes
ncfb: 16 bytes
nofb: 16 bytes
ofb: 16 bytes
stream: not supported
xtea
cbc: 8 bytes
cfb: 8 bytes
ctr: 8 bytes
ecb: 8 bytes
ncfb: 8 bytes
nofb: 8 bytes
ofb: 8 bytes
stream: not supported
blowfish
cbc: 8 bytes
cfb: 8 bytes
ctr: 8 bytes
ecb: 8 bytes
ncfb: 8 bytes
nofb: 8 bytes
ofb: 8 bytes
stream: not supported
enigma
cbc: not supported
cfb: not supported
ctr: not supported
ecb: not supported
ncfb: not supported
nofb: not supported
ofb: not supported
stream: 1 bytes
rc2
cbc: 8 bytes
cfb: 8 bytes
ctr: 8 bytes
ecb: 8 bytes
ncfb: 8 bytes
nofb: 8 bytes
ofb: 8 bytes
stream: not supported
tripledes
cbc: 8 bytes
cfb: 8 bytes
ctr: 8 bytes
ecb: 8 bytes
ncfb: 8 bytes
nofb: 8 bytes
ofb: 8 bytes
stream: not supported
Therefore you have to rtrim()
the output of the decryption functions to get the original string if your cipher operates on fixed length blocks:
$output = rtrim($decrypted, "\0");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With