DES填充方式与初始向量IV的作用
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加解密在线工具