pkcs5 padding和pkcs7 padding都是加密数据时用来填充数据的一种模式。
先说下block_size,即块大小。在加密算法中(如DES,AES,RSA),数据是分块加密的(为什么要分块,因为整块加密数据量有可能太大)。分块的话,就得按照一定的长度即block_size来分,大多数加密算法中的分块大小默认都是64bits,即8个字节,block_size=8。如果需要加密的数据(明文)的字节码的长度不是块大小的整数倍,那么就需要在末尾进行填充。那么如何填充呢?这就是本文要说的pkcs5和pkcs7填充模式(还有pkcs1,用于RSA加密算法,比较复杂,这里不说了,自行百度)。
重点:PKCS #5 填充字符串由一个1~8位的字节序列组成,每个字节填充“该字节序列的长度”。
使用PKCS5,填充时:
要填充7个字节,那么填入的值就是0×07;
如果只填充1个字节,那么填入的值就是0×01;
示例:
PKCS5的块长度为 8
数据长度为 9时,则填充为8位字节的倍数,需要补7位字节,即填充字节序列的长度等于 7,则每个字节应填充07,示例如下:
数据: FF FF FF FF FF FF FF FF FF
PKCS7 填充: FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07
数据长度为 10时,则填充为八位字节的倍数,需要补6位字节,即填充字节序列的长度等于 6,则每个字节应填充06,示例如下:
数据: FF FF FF FF FF FF FF FF FF FF
PKCS7 填充: FF FF FF FF FF FF FF FF FF FF 06 06 06 06 06 06
另外:还有一种情况就是数据长度恰好是8的倍数,那么后面还需要填充吗?
答案是:需要,数据恰好是8的倍数时还要补8个字节的0×08。
正是这种即使恰好是8的倍数也需要再补充字节的规定,可以让解密算法在解密数据后,很确定无误的移除多余的字节。
让我们做一个假设:如果有一个明文恰好是:FF FF FF FF FF FF FF FF FF FF 06 06 06 06 06 06
那么解密后,我怎么知道后面的6个06就是原来的明文,还是末尾的填充?如果我把后面的6位06 06 06 06 06 06当成padding给去掉的话,就破坏了原文,导致解密后的明文与原来的明文不一致。
解决方法就是,这种情况下,明文填充后应该是:FF FF FF FF FF FF FF FF FF FF 06 06 06 06 06 06 08 08 08 08 08 08 08 08,这样的话,就不会出现混乱。解密算法可以确定最后面的8位一定是填充数据,从而避免出现错误。
最后,说一下PKCS7和PKCS5的区别就是数据分块的大小(就是这么简单):
- PKCS5填充块的大小为8bytes(64位)
- PKCS7填充块的大小可以在1-255bytes之间。
综上所述,可以说PKCS7是兼容PKCS5的,PKCS5相当于PKCS7的一个子集。
因为AES的要求的分块长度固定为128 比特(密钥key长度则可以是128,192或256比特),所以填充方法一定是PKCS7
本文参考:https://www.cnblogs.com/midea0978/articles/1437257.html