DES的幾種填補方式
DES是對64位數據的加密算法,如數據位數不足64位的倍數,需要填充,補充到64位的倍數。
NoPadding
API或算法本身不對數據進行處理,加密數據由加密雙方約定填補算法。例如若對字符串數據進行加解密,可以補充\0或者空格,然后trim
PKCS5Padding
加密前:數據字節長度對8取余,余數為m,若m>0,則補足8-m個字節,字節數值為8-m,即差幾個字節就補幾個字節,字節數值即為補充的字節數,若為0則補充8個字節的8
解密后:取最后一個字節,值為m,則從數據尾部刪除m個字節,剩余數據即為加密前的原文
因為DES是一種block cipher,一個block要8個字節,所以要加密的東西要分成8字節的整數倍,不足的就填充。
PKCS5Padding這種填充,填的字節代表所填字節的總數:
比如差三個字節的話填為 @@@@@333 差7個字節就填為 @7777777 沒有差就填 88888888
下面兩種摘自wiki:
ISO 10126
ISO 10126 specifies that the padding should be done at the end of that last block with random bytes, and the padding boundary should be specified by the last byte.
Example: In the following example the block size is 8 bytes and padding is required for 4 bytes
... | DD DD DD DD DD DD DD DD | DD DD DD DD 81 A6 23 04 |
意思就是前面隨機填充,最后一個字節填充總共補充的字節數。
Zero padding
All the bytes that are required to be padded are padded with zero. The zero padding scheme has not been standardized for encryption, although it is specified for hashes and MACs as Padding Method 1 in ISO/IEC 10118-1 and ISO/IEC 9797-1.
Example: In the following example the block size is 8 bytes and padding is required for 4 bytes
... | DD DD DD DD DD DD DD DD | DD DD DD DD 00 00 00 00 |
Zero padding may not be reversible if the original file ends with one or more zero bytes, making it impossible to distinguish between plaintext data bytes and padding bytes. It may be used when the length of the message can be derived out-of-band. It is often applied to binary encoded strings as the null character can usually be stripped off as whitespace.
Zero padding is sometimes also referred to as "null padding" or "zero byte padding". Some implementations may add an additional block of zero bytes if the plaintext is already divisible by the block size.
不足8位補 0,有可能會出問題,因為不知道數據本身會不會以一個或多個 0 字節結尾。
關於DES/CBC模式的向量:
在CBC(不光是DES算法)模式下,iv通過隨機數(或偽隨機)機制產生是一種比較常見的方法。iv的作用主要是用於產生密文的第一個block,以使最終生成的密文產生差異(明文相同的情況下),使密碼攻擊變得更為困難,除此之外iv並無其它用途。最大的好處是,即使相同的明文,相同的密鑰,也能產生不同的密文。
使用在線工具進行驗證,對於相同的明文,密鑰,使用相同的向量時,多次實驗生成的密文是一樣的;而使用不同的密鑰時,生成的密文差別很大,證實了向量的作用。
實際使用過,發現即使使用錯誤的向量,有時也能正常解密出數據(數據在解密后進行了解壓縮操作,能正常解壓即認為是解密正確),覺得奇怪,在線驗證了一下,發現使用正確密鑰、錯誤向量,解密出來的數據其實並不正確。向量錯誤時,解密出來數據的前8字節會與原明文有所不同,而后面所有的字節都完全正確,而且,前面錯誤的地方與向量錯誤的位數剛好對應,比如向量的第5個字節錯誤,則解密出來的數據第5個字節是錯的,其它均正確。
出現上述現象,是因為CBC模式在加密時,只會使用向量與第一個明文分組進行異或、加密得到第一組密文,從第二組之后的每一次操作都將前一組密文與明文進行異或、加密,得到密文;因此在解密時只在解密第一個分組時需要使用向量,而之后的分組,使用的是前一個密文分組,因此向量錯誤時不會影響后面的分組解密。
另外有一點疑惑,使用 jdk 自帶的類庫,同樣的明文、密鑰、向量,產生的密文不一樣,應該是加入了隨機機制,具體原因待分析。
參考: DES加解密在線工具