關於PKCS5Padding與PKCS7Padding的理解

前言

在採用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]
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章