I have a code that goes something like:
$cipher_alg = MCRYPT_RIJNDAEL_128;
$decrypted_string = mcrypt_decrypt($cipher_alg, $key,
$encrypted_string , MCRYPT_MODE
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 * <
. The padding character is the NUL
character (\x0
or \0
) whereas the <
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");