php:三種填充模式的區別(PKCS7Padding/PKCS5Padding/ZeroPadding)

長話短說,寫這篇文章主要是爲了補下這篇文章的相關知識點 aes加密使用mcrypt_decrypt能解開,openssl_decrypt卻解不開。

 

常見的三種填充方式:

我們知道某些加密算法要求明文需要按一定長度對齊,叫做塊大小(BlockSize),比如16字節,那麼對於一段任意的數據,加密前需要對最後一個塊填充到16 字節,解密後需要刪除掉填充的數據。

  • ZeroPadding,數據長度不對齊時使用0填充,否則不填充。使用0填充有個缺點,當元數據尾部也存在0時,在unpadding時可能會存在問題。
  • PKCS7Padding,假設數據長度需要填充n(n>0)個字節纔對齊,那麼填充n個字節,每個字節都是n;如果數據本身就已經對齊了,則填充一塊長度爲塊大小的數據,每個字節都是塊大小。
  • PKCS5Padding,PKCS7Padding的子集,塊大小固定爲8字節,填充方式和PKCS7Padding一樣。

由於使用PKCS7Padding/PKCS5Padding填充時,最後一個字節肯定爲填充數據的長度,所以在解密後可以準確刪除填充的數據,而使用ZeroPadding填充時,沒辦法區分真實數據與填充數據,所以只適合以\0結尾的字符串加解密。

 

字符'0'和'\0',及整數0的區別

php的底層是c,所以以c語言爲標準;

字符型char和整型int;

字符型變量用於存儲一個單一字符,在 C 語言中用 char 表示,其中每個字符變量都會佔用 1 個字節(8位二進制數)。

整型int在內存中佔用空間爲四個字節(32位二進制數)

字符'0':char c = '0'; 它的ASCII碼實際上是48。內存中存放表示:00110000

字符'\0' :ASCII碼爲0,表示一個字符串結束的標誌。這是轉義字符(整體視爲一個字符)。由於內存中存儲字符,依然是存儲的是對應字符集的字符編碼;所以內存中的表現形式爲00000000

整數0 :內存中表示爲:00000000 00000000 00000000 00000000;雖然都是0,但是跟上面字符'\0'存儲佔用長度是不一樣的;

 

 

php PKCS7Padding和ZeroPadding填充方法如下:

#PKCS7
public static function pad($data, $blocksize = 16)
{
    $pad = $blocksize - (strlen($data) % $blocksize);
    return $data . str_repeat(chr($pad), $pad);
}
                
public static function unpad($text)
{
    $pad = ord($text[strlen($text) - 1]);
                        
    if ($pad > strlen($text))
    {
        return false;
    }
                            
    if (strspn($text, chr($pad), strlen($text) - $pad) != $pad)
    {
        return false;
    }
                        
    return substr($text, 0, -1 * $pad);
}


#zero
public static function padZero($data, $blocksize = 16)
{
    $pad = $blocksize - (strlen($data) % $blocksize);
    return $data . str_repeat("\0", $pad);
}
            
public static function unpadZero($data)
{
    return rtrim($data,"\0");
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章