kapitanluffy
kapitanluffy

Reputation: 1267

PHP PKCS7 Padding bug

I am trying to apply PKCS7 padding to my PHP code. I derived my code from this gist

https://gist.github.com/Halama/5956871

The blocksize is expected to be 16 bytes. The data is "password" with a length of 8 bytes. After getting the pad, it will append it at the end of the data to be encrypted.

$blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, $thisMCRYPT_MODE_CBCmode);
$pad = $blockSize - (strlen($data) % $blockSize);
$data = $data . str_repeat(chr($pad), $pad);

The problem is there are (a lot) of instances that where the data fails to decrypt it.

Provided below are base64 encoded sample data. The first 16 bytes of the decoded sample represents the IV

working: cjg1RYWxlc8bDH2de43t0bv1ug36i8ayjWDQTela938= (pad length: 8)

not working: 9wWI+MyYj5ZVj2sC4xr7EgOsgNSoeTZW1yM8ddmqg18= (pad length: 122)

The pad length mentioned above is retrieved using this

$pad = ord($data[strlen($data) - 1]);

I am using mcrypt_enrypt to encrypt the string "password". The key I am using for mcrypt is

lGbsVE+qVO1P2ue0iCjrTPMU5hKX9aHE7r1aUUeqFag=

Upvotes: 0

Views: 1462

Answers (2)

kapitanluffy
kapitanluffy

Reputation: 1267

solved it. the "+" signs in the base64 encoded data is being converted to spaces when transported through http thus resulting into different values.

What I did is the client encoded the binary data to base64 and passed it through urlencode() function. The PHP side handled the data by using rawurldecode so it will ignore the "+" signs.

Upvotes: 0

Maarten Bodewes
Maarten Bodewes

Reputation: 94038

The padding/unpadding routine looks correct. What it does not provide is a safeguard against padding values higher than the block size.

If a ciphertext is decrypted using a wrong key, or if the ciphertext is corrupted (and for short sized ciphertext, even if the IV is incorrect), the result will be a (padded) plaintext that has seemingly random data. So the last byte can have any random value during the unpadding of the incorrect result.

To protect against such failures, use a MAC value over the ciphertext, preferably using a different key. For now, the issue is not likely to be the (un)padding routine.

Upvotes: 0

Related Questions