PKCS#5填充和PKCS#7填充兼容吗?
#1 楼
PKCS#5和PKCS#7填充机制之间的差异在于块大小; PKCS#5填充定义为8字节的块大小,PKCS#7填充将适用于1到255字节的任何块大小。这是PKCS#5填充(6.2)的定义为在RFC中定义:
填充字符串PS应当由8-(|| M || mod 8)个八位字节组成,所有八位字节
的值为8-(|| M | | mod 8)。
包含PKCS#7标准的RFC相同,只是它允许的块大小最大为255个字节(10.3注2):
对于此类算法,方法应为在
末尾用k-(l mod k)个八位字节填充输入,这些八位字节均具有值k-
(l mod k),其中l是输入的长度。
因此从根本上来说,PKCS#5填充是PKCS#7填充的一个子集,用于8个字节的块大小。因此,PKCS#5填充不能用于AES。 PKCS#5填充仅在考虑了RC2 / RC5和(三重)DES操作的情况下定义。
许多密码库使用一个标识符来指示PKCS#5或PKCS#7定义相同的填充机制。如果在计算中使用的块大小不是8,则标识符应指示PKCS#7。一些密码库(例如Java中的SUN提供程序)指示PKCS#5应该在其中使用PKCS#7-
"PKCS5Padding"
应该是"PKCS7Padding"
。自从只有8个字节的块密码(例如(三重)DES对称密码)可用以来,这是一个很大的遗产。请注意,PKCS#5和PKCS#7都不是用来描述填充机制的标准。填充部分只是所定义功能的一小部分。 PKCS#5是基于密码的加密或PBE的标准,而PKCS#7定义了加密消息语法或CMS。从这个意义上讲,您可以说ECB和CBC模式可以使用PKCS#5或PKCS#7兼容的填充。后来的PKCS#5标准仅将PKCS#7 CMS标准的后继用于AES等16字节块密码。
评论
$ \ begingroup $
1:块大小为1时,任何块大小为1的PKCS#7似乎都不太有用,并且并非所有软件都可以信任blocksize = 1的PKCS#7。哪一个是正确的(最多256个字节或255个字节)?对我来说,它将出现$ k <256 $,因此最多255个字节。
$ \ endgroup $
–user4982
2014年1月5日在21:32
$ \ begingroup $
@ user4982:$ k $个八位位组分组密码的PKCS#7填充的定义为“在末尾用$ k-(l \ bmod k)$个八位位组填充输入,所有八位位组均具有$ k-( l \ bmod k)$,其中$ l $是输入的长度“不适用于$ k = 256 $(请注意,对于$ l $乘以$ k $的整数,它是规定值256美元的八位字节,是错的)。正确的扩展名是“在末尾用$ k-(l \ bmod k)$个八位位组填充输入,这些八位位组均具有值$(k-(l \ bmod k))\ bmod k $,其中$ l $是输入的长度”。
$ \ endgroup $
–fgrieu♦
2014年1月6日,11:41
$ \ begingroup $
@ user4982 blocksize = 1没什么用,但有可能。 blocksize = 1仅对流密码有意义,并且流密码不需要填充。我已经解释了256值是互斥的,但是由于当前密码通常具有最多256位(32字节)的块,因此永远不会达到最大值。对于更灵活(更好的IMHO)填充机制,请使用位填充(将单个位设置为1,然后全为零)。
$ \ endgroup $
–马腾·博德威斯♦
2014年1月6日在18:28
$ \ begingroup $
是的。如果您需要更大的填充大小,则可能需要使用其他方案。位填充:0x80,后跟多个0x00值的字节(对于在字节级别指定的协议)是一个很好的填充方案,如果对于大量填充来说有些尴尬,因为您必须测试所有值为零的字节。对于大多数分组密码/操作模式,最大值当然是16或32:请勿将分组密码填充用于例如隐藏明文长度,并不是为了有效地做到这一点而设计的,您将在协议的不同级别混合方案。
$ \ endgroup $
–马腾·博德威斯♦
18年1月2日,14:01
$ \ begingroup $
Nit / update:支持原始PKCS5(单个)的DES和RC2(均为8字节块)。 2017年的v2.1(rfc8018)添加了AES,TDES和RC5及其填充参考CMS(rfc5652),后者是PKCS7的最新后代。当然,当今使用的几乎所有加密API都是在2017年之前设计的。
$ \ endgroup $
–dave_thompson_085
19年12月30日,下午3:58