前言
在采用AES、DES等块加密时,有时需要对不满足一个整块(block)的部分需要进行填充,我们常用的填充的方式就包括ZeroPadding、PKCS5Padding与PKCS7Padding,这里面有什么区别呢。
填充方式的区别
ZeroPadding,数据长度不对齐时使用0填充,否则不填充。使用0填充有个缺点,当元数据尾部也存在0时,在unpadding时可能会存在问题。
我们这里主要讨论PKCS7Padding与PKCS5Padding。
这是RFC中关于PKCS7的具体填充过程:
Some content-encryption algorithms assume the input length is a multiple of k octets, where k is greater than one. For such algorithms, the input shall be padded at the trailing end with k-(lth mod k) octets all having value k-(lth mod k), where lth 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 lth mod k = k-1
02 02 -- if lth mod k = k-2
.
.
.
k k ... k k -- if lth mod k = 0
The padding can be removed unambiguously since all input is padded,including input values that are already a multiple of the block size,and no padding string is a suffix of another. This padding method is well defined if and only if k is less than 256.
(1)PKCS7Padding,
假设每个区块大小为blockSize
<1>已对齐,填充一个长度为blockSize且每个字节均为blockSize的数据。
<2>未对齐,需要补充的字节个数为n,则填充一个长度为n且每个字节均为n的数据。
(2)PKCS5Padding,PKCS7Padding的子集,只是块大小固定为8字节。
两者的区别在于PKCS5Padding是限制块大小的PKCS7Padding
具体代码实现
按照以上的定义,我们用golang实现如下:
func PKCS7Padding(cipherText []byte, blockSize int) []byte {
padding := blockSize - len(cipherText)%blockSize
padText := bytes.Repeat([]byte{byte(padding)}, padding)
return append(cipherText, padText...)
}
func PKCS5Padding(cipherText []byte) []byte {
return PKCS7Padding(cipherText, 8)
}
在解密后,需要将填充的字符去掉,取最后一位即知道存在多少个补充位,实现如下:
func unpadding(src []byte) []byte {
n := len(src)
if n == 0 {
return src
}
paddingNum := int(src[n-1])
return src[:n-paddingNum]
}
原文链接:https://blog.csdn.net/xz_studying/article/details/94229023