Fewmitz
Fewmitz

Reputation: 497

Encryption - PKCS5/7 padding race condition?

I'm writing some crypto (known algorithm - not rolling my own) but I couldn't find any specific documentation on this case.

One method of padding (although the issue is there for any of them could have the same problem) works like this:

If your block is < 8 bytes, pad the end with the number of padding bytes

So FF E2 B8 AA becomes FF E2 B8 AA 04 04 04 04

Which is great and allows you with a pretty obvious window with which you can remove padding during decryption, but my question is that instead of the above example say I have this -

10 39 ff ef 09 64 aa (7 bytes in length). Now in this situation the above algorithm would say to convert this to 10 39 ff ef 09 64 aa 01, but my question is then when decrypting how do you decide between when you get a 01 byte on the end of a decrypted message how do you know whether it's meant to be padding (and should be stripped) or it's part of the actual message and you should keep it?

The most reasonable solutions I can think of would be append/prepend the size of the actual message in the encryption or add a parity block to state whether there's padding or not, which both have their own problems in my mind.

I'm assuming this problem has been encountered before but I was wondering what the solution was.

Upvotes: 2

Views: 269

Answers (1)

ntoskrnl
ntoskrnl

Reputation: 5744

PKCS #5/7 padding is always added – if the length of the plaintext is a multiple of the block size, a whole block of padding is added. This way there is no ambiguity, which is the main benefit of PKCS #7 over, say, zero padding.

Quoted from the PKCS #7 specification:

    2.   Some content-encryption algorithms assume the
         input length is a multiple of k octets, where k > 1, and
         let the application define a method for handling inputs
         whose lengths are not a multiple of k octets. For such
         algorithms, the method shall be to pad the input at the
         trailing end with k - (l mod k) octets all having value k -
         (l mod k), where l is the length of the input. In other
         words, the input is padded at the trailing end with one of
         the following strings:

                  01 -- if l mod k = k-1
                 02 02 -- if l mod k = k-2
                             .
                             .
                             .
               k k ... k k -- if l mod k = 0

         The padding can be removed unambiguously since all input is
         padded and no padding string is a suffix of another. This
         padding method is well-defined if and only if k < 256;
         methods for larger k are an open issue for further study.

Upvotes: 6

Related Questions