PKCS7
是当下各大加密算法都遵循的填充算法,且 OpenSSL
加密算法簇的默认填充算法就是 PKCS7
。php
其实PKCS7
理解起来很是简单,使用需填充长度的数值 paddingSize
所表示的ASCII
码 paddingChar = chr(paddingSize)
对数据进行冗余填充。算法
为何是冗余填充呢?由于即使你的数据长度符合blockSize
的整数倍时,也须要填充,填充的长度反而是最大的,要填充blockSize
个char(blockSize)
字符在数据尾部,这样牺牲了数据长度的作法是为了更为灵活透明的去解包数据,发送端和接收端不须要约定好blockSize
,接收端总能经过数据包的最后一个字符获得填充的数据长度。加密
当咱们拿到一串PKCS7
填充的数据时,取其最后一个字符paddingChar
,此字符的ASCII
码的十进制ord(paddingChar)
即为填充的数据长度paddingSize
,读取真实数据时去掉填充长度便可substr(content, 0, -paddingSize)
。code
填充示例,好比数据块blockSize
为 8ip
h<0x07><0x07><0x07><0x07><0x07><0x07><0x07> 7 he<0x06><0x06><0x06><0x06><0x06><0x06> 6 hel<0x05><0x05><0x05><0x05><0x05> 5 hell<0x04><0x04><0x04><0x04> 4 hello<0x03><0x03><0x03> 3 hello <0x02><0x02> 2 hello w<0x01> 1 hello wo<0x08><0x08><0x08><0x08><0x08><0x08><0x08><0x08> 8 // 数据块 hello wor<0x07><0x07><0x07><0x07><0x07><0x07><0x07> 7 hello word<0x06><0x06><0x06><0x06><0x06><0x06> 6
实现:string
/** * PKCS7填充 * @param string $content 待填充内容 * @param int $block_size 待填充内容数据块长度 */ function pkcs7_padding($content, $block_size) { if (255 < $block_size || 0 >= $block_size) { throw new \Exception("the block size pkcs7 can padding is (0 ~ 255] "); } // 待填充的长度 $padding_size = $block_size - (strlen($content) % $block_size); // 待填充的字符 $padding_char = chr($padding_size); $content .= str_repeat($padding_char, $padding_size); return $content; } /** * 移除PKCS7 * @param string $content * @return string */ function pkcs7_strip($content) { $padding_char = substr($content, -1); $padding_size = ord($padding_char); $content = substr($content, 0, -$padding_size); return $content; } $content = pkcs7_padding("hello", $block_size); echo pkcs7_strip($content);
pkcs5
做为pkcs7
的子集算法,概念上没有什么区别,只是在blockSize
上固定为 8 位,即数据始终会被切割成 8 个字节的数据块,而后计算须要填充的长度。pkcs7
的填充长度blockSize
是 1~255
。io