PKCS7 / PKCS5 填充算法

PKCS7

PKCS7是當下各大加密算法都遵循的填充算法,且 OpenSSL 加密算法簇的默認填充算法就是 PKCS7php

其實PKCS7理解起來很是簡單,使用需填充長度的數值 paddingSize 所表示的ASCIIpaddingChar = chr(paddingSize)對數據進行冗餘填充。算法

爲何是冗餘填充呢?由於即使你的數據長度符合blockSize的整數倍時,也須要填充,填充的長度反而是最大的,要填充blockSizechar(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

pkcs5做爲pkcs7的子集算法,概念上沒有什麼區別,只是在blockSize上固定爲 8 位,即數據始終會被切割成 8 個字節的數據塊,而後計算須要填充的長度。pkcs7的填充長度blockSize1~255io

相關文章
相關標籤/搜索