99
$\begingroup$

One runtime platform provides an API that supplies PKCS#5 padding for block cipher modes such as ECB and CBC. These modes have been defined for the triple DES, AES and Blowfish block ciphers. The other platform API only provides PKCS#7 padding.

Are PKCS#5 padding and PKCS#7 padding compatible?

$\endgroup$
0

1 Answer 1

122
$\begingroup$

The difference between the PKCS#5 and PKCS#7 padding mechanisms is the block size; PKCS#5 padding is defined for 8-byte block sizes, PKCS#7 padding would work for any block size from 1 to 255 bytes.

This is the definition of PKCS#5 padding (6.2) as defined in the RFC:

The padding string PS shall consist of 8 - (||M|| mod 8) octets all having value 8 - (||M|| mod 8).

The RFC that contains the PKCS#7 standard is the same except that it allows block sizes up to 255 bytes in size (10.3 note 2):

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.

So fundamentally PKCS#5 padding is a subset of PKCS#7 padding for 8 byte block sizes. Hence, PKCS#5 padding can not be used for AES. PKCS#5 padding was only defined with RC2/RC5 and (triple) DES operation in mind.

Many cryptographic libraries use an identifier indicating PKCS#5 or PKCS#7 to define the same padding mechanism. The identifier should indicate PKCS#7 if block sizes other than 8 are used within the calculation. Some cryptographic libraries such as the SUN provider in Java indicate PKCS#5 where PKCS#7 should be used - "PKCS5Padding" should have been "PKCS7Padding". This is - with high probability - a legacy from the time that only 8 byte block ciphers such as (triple) DES symmetric cipher were available.

Note that neither PKCS#5 nor PKCS#7 is a standard created to describe a padding mechanism. The padding part is only a small subset of the defined functionality. PKCS#5 is a standard for Password Based Encryption or PBE, and PKCS#7 defines the Cryptographic Message Syntax or CMS. In that sense you could say that ECB and CBC mode can use PKCS#5 or PKCS#7 compatible padding. Later PKCS#5 standards simply refer to successors of the PKCS#7 CMS standard for 16 byte block ciphers such as AES.

$\endgroup$
8
  • $\begingroup$ any block size from 1: PKCS#7 does not appear to be very useful with block size of 1, and not all software can be trusted to support PKCS#7 with blocksize=1. Which one is correct up to 256 bytes or to 255 byte? To me it would appear $k < 256$, thus up to 255 bytes. $\endgroup$
    – user4982
    Commented Jan 5, 2014 at 21:32
  • $\begingroup$ @user4982: the definition of PKCS#7 padding for $k$-octet block cipher as "pad the input at the trailing end with $k-(l\bmod k)$ octets all having value $k-(l\bmod k)$, where $l$ is the length of the input" is not applicable to $k=256$ (notice that for $l$ multiple of $k$, it is prescribed octets with value $256$, which is wrong). A correct extension would be "pad the input at the trailing end with $k-(l\bmod k)$ octets all having value $(k-(l\bmod k))\bmod k$, where $l$ is the length of the input". $\endgroup$
    – fgrieu
    Commented Jan 6, 2014 at 11:41
  • 1
    $\begingroup$ @user4982 blocksize=1 is not useful but possible. blocksize=1 only makes sense for stream ciphers, and stream ciphers do not need padding. I've explained that the 256 value is exclusive, but as current ciphers have normally a maximum of 256 bit (32 byte) blocks, so the maximum is never reached. For a more flexible (and IMHO better) padding mechanism, use bit padding (a single bit set to one, followed by all zero bits). $\endgroup$
    – Maarten Bodewes
    Commented Jan 6, 2014 at 18:28
  • 1
    $\begingroup$ That's correct. If you need a larger padding size then you may need to move to another scheme. Bit padding: 0x80 followed by as many 0x00 valued bytes (for protocols specified at the byte level) is a good padding scheme, if somewhat awkward for very large amounts of padding as you must test all the bytes valued zero. For most block ciphers / mode of operation the maximum is of course 16 or 32: don't use block cipher padding to e.g. hide plaintext length, it wasn't designed to do that efficiently and you'd be mixing schemes at different levels in the protocol. $\endgroup$
    – Maarten Bodewes
    Commented Jan 2, 2018 at 14:01
  • 1
    $\begingroup$ Nit/update: original PKCS5 supported (single) DES and RC2 -- both with 8-byte block. v2.1 in 2017 (rfc8018) adds AES as well as TDES and RC5 and for its padding references CMS (rfc5652) which is the current descendant of PKCS7. Of course nearly all crypto APIs used today were designed before 2017. $\endgroup$ Commented Dec 30, 2019 at 3:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.