Saturday, November 6, 2010

How Padding Affects Block Cipher Encryption: PKCS7Padding vs ISO10126Padding

Why Padding:

To understand why you need to use padding in block cipher encryption, you need to first understand what a block cipher is? A block cipher is an encryption algorithm which operates on a fixed length of bits or block of input data size for encryption. A block cipher requires that input which needs to be encrypted has to be multiple of this block size.

So there you go, since not all input will be a multiple of this block size, you need to use padding to add additional bits to the input data to make it a multiple of block size before doing encryption using a block cipher. Similarly when doing decryption the padding needs to be removed to obtained the original input which was encrypted.

To given an example, a block cipher like AES (aka Rijndael) has a fixed block size of 128 bits and a key size of 128, 192, or 256 bits. So any input which is  encrypted or decrypted needs to be a multiple of 128 bits.

What happens if you use a wrong padding?

It is very important that one use the same padding scheme for both encryption and decryption. A padding is part of contract for a successful encryption and decryption. First lets look at two padding schemes:

PKCS7Padding:

The PKCS #7 padding string consists of a sequence of bytes, each of which has value equal to the total number of padding bytes added.

The following example shows how these modes work. Given a block cipher of 8 bytes size, If input data length is 9 bytes, then number of padding bytes equal to 7 bytes, each having value as 07.

Data: FF FF FF FF FF FF FF FF FF

PKCS7 padding: FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07

ISO10126Padding:

The ISO10126 padding string consists of random value data and the last byte has the value of total number of padding bytes added.

The following example shows how this mode works. Given a block cipher of 8 bytes size, If input data length is 9 bytes, then number of padding bytes equal to 7 bytes, the first 6 bytes will have random value and last one will have value 07 to denote total number of padding bytes added.

Data: FF FF FF FF FF FF FF FF FF

ISO10126 padding: FF FF FF FF FF FF FF FF FF 7D 2A 75 EF F8 EF 07

Using PKCS7Padding for encryption and ISO10126Padding for decryption:

Now to illustrate what wrong could happen, assume that a system is designed for password encryption using AES 256 bit key size and it is using PKCS7Padding for encryption and decryption for password. Everything works fine. Now a few years later a new system is designed which will decrypt the password and use it. Now see what happens if it uses a wrong padding:


The new system by mistake starts using ISO10126Padding padding when doing password decryption.
The surprising thing is that decryption will work!!! If you look at the example of paddings above, the ISO10126Padding will read last 07 bytes of data encoded with PKCS7Padding (FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07) and will find 07 as the last byte value and remove the last 7 bytes.

Using ISO10126Padding for encryption and PKCS7Padding for decryption:

Now assume that this new system also starts encrypting password and it uses ISO10126Padding.
If the old system tried to decrypted this password using PKCS7Padding it will most like fail with pad block corruption error. To see why if you look at the example of paddings above, the PKCS7Padding will read data padded with ISO10126Padding (FF FF FF FF FF FF FF FF FF 7D 2A 75 EF F8 EF 07) and will find 07 as the last byte value so based on PKCS7Padding scheme it will try to validate that last 7 bytes should have 07 as the value, but they are not so it will result in an error.

So in essence it is very important to make sure when designing any new system which rely on old legacy encryption contract to follow the same padding scheme or you will end up with subtle errors like the one I highlighted above and will bite you later.

Promote your blog