hi,大家好,上一节我们详细介绍了对称加密算法DES的基本内容,由于明文的长度不固定,而加密算法只能处理特定长度的一块数据,所以就需要对比较长的明文进行分组后再加密,但是分组后,最后一组的长度可能又会出现位数长度不够的情况,所以就又需要根据填充模式来对最后一组报文进行填充。
对称加密的分组模式
对称加密一共有五种分组模式,下面我们来介绍一下。
1. ECB - Electronic Code Book, 电子密码本模式
优点:
- 简单,效率高
- 有利于并行计算
- 误差不会被传送
缺点:
- 密文有规律,容易被破解
- 可能对明文进行主动攻击
特性:
最后一个明文分组必须要填充
- des/3des -> 最后一个分组填充满8字节
- aes -> 最后一个分组填充满16字节
- 不需要初始化向量
2. CBC - Cipher Block Chaining, 密码块链模式(推荐使用)
优点:
- 不容易被攻击,安全性好
- 适合传输长度长的报文
- 是SSL、IPSec的标准
缺点:
- 不利于并行计算
- 误差会传递
- 需要初始化向量
特性:
最后一个明文分组需要填充
- des/3des -> 最后一个分组填充满8字节
- aes -> 最后一个分组填充满16字节
需要一个初始化向量 - 一个数组
- 数组的长度: 与明文分组相等
- 数据来源: 负责加密的人的提供的
- 加解密使用的初始化向量值必须相同
3. CFB - Cipher FeedBack, 密文反馈模式
优点:
- 隐藏了明文模式,密文没有规律
- 分组密码转化为流模式
- 可以及时加密传送小于分组的数据
缺点:
- 不利于并行计算
- 误差传递:一个明文单一损坏影响多个单元
- 需要初始化向量
特性: 明文分组是和一个数据流进行的按位异或操作, 最终生成了密文
需要一个初始化向量 - 一个数组
- 数组的长度: 与明文分组相等
- 数据来源: 负责加密的人的提供的
- 加解密使用的初始化向量值必须相同
- 不需要填充
4. OFB - Output-Feedback,输出反馈模式
优点:
- 隐藏了明文模式
- 分组密码转化为流模式
- 可以及时加密传送小于分组的数据
缺点:
- 不利于并行计算
- 对明文的主动攻击是可能的
- 误差传送:一个明文单元的损坏影响多个单元
特性: 密文没有规律,明文分组是和一个数据流进行的按位异或操作,最终生成了密文
需要一个初始化向量 - 一个数组
- 数组的长度: 与明文分组相等
- 数据来源: 负责加密的人的提供的
- 加解密使用的初始化向量值必须相同
- 不需要填充
5. CTR - CounTeR,计数器模式(重点,推荐使用)
特性:
- 密文没有规律,明文分组是和一个数据流进行的按位异或操作,最终生成了密文
- 不需要初始化向量
- 不需要填充
以上五种分组模式中,ECB模式很容易被破解,如今已经很少再使用,其余四种分组模式各有千秋。
但极力推荐CBC模式和CTR模式,尤其是CTR模式,不需要填充,代码实现起来很方便。而且加密和解密的方法是一样的,并且可以实现并发分组,效率高,安全性也有保障。
关于CBC模式中的向量:
在CBC(不光是DES算法)模式下,向量iv通过随机数(或伪随机)机制产生是一种比较常见的方法。iv的作用主要是用于产生密文的第一个block,以使最终生成的密文产生差异(明文相同的情况下),使密码攻击变得更为困难,除此之外iv并无其它用途。最大的好处是,即使相同的明文,相同的密钥,也能产生不同的密文。
对称加密的填充模式
数据填充常见的一般有四种,分别是:
- NoPadding
- PKCS5Padding (PKCS7Padding)
- Zero Padding
- ISO 10126 Padding
NoPadding
API或算法本身不对数据进行处理,加密数据由加密双方约定填补算法。例如若对字符串数据进行加解密,可以补充\0或者空格,解密后对数据进行trim 处理。
PKCS5Padding (PKCS7Padding)
PKCS5Padding 、PKCS7Padding分别为Java和.Net中的默认填充方式,PKCS5Padding和PKCS7Padding实际只是协议不一样,根据相关资料说明,PKCS5Padding明确定义了加密块是8字节,PKCS7Padding加密块可以是1-255之间。但是封装的DES算法默认都是8字节,所以可以认为他们是一样的。数据补位实际是在数据不满8字节的倍数,才补充到8字节的倍数的填充过程。
加密前:数据字节长度对8取余,余数为m,若m>0,则补足8-m个字节,字节数值为8-m,即差几个字节就补几个字节,字节数值即为补充的字节数,若为0则补充8个字节的8
解密后:取最后一个字节,值为m,则从数据尾部删除m个字节,剩余数据即为加密前的原文
比如:加密字符串为为AAA,差5个字节,则补位为AAA55555;加密字符串为BBBBBB,差2个字节,则补位为BBBBBB22;加密字符串为CCCCCCCC,差0个字节,则补位为CCCCCCCC88888888。
Zero Padding
0填充,顾名思义就是所有不足8位的均补0,不过0填充协议并没有在加密算法中标准化,而且0填充可能会有问题,当明文本身有一个或多个0字节结尾时,就很难区分是填充的0还是原报文。
例如:下面是一个以8字节为单位的加密块,最后四个字节不足位时,使用0来填充
... | DD DD DD DD DD DD DD DD | DD DD DD DD 00 00 00 00 |
ISO 10126
ISO 10126 的填充模式定义了在报文最后一个字节填充之前的字节都可以随机填充,在最后一个字节填充总共补充的字节数。
例如: 下面例子,最后一共需要补充4个字节,前三个字节都是随机填充的字节,最后一个字节需要填充4,表示该填充总共填充了4字节。
... | DD DD DD DD DD DD DD DD | DD DD DD DD 81 A6 23 04 |
何时需要填充,何时不需要填充?
观察分组模式的图示可以看出,加密后再进行亦或操作的不需要填充,而先进性亦或操作再加密的则不需要填充,这是因为亦或操作需要两个相同长度的数据,一一对比计算!
总结
以上五种分组模式中,ECB模式很容易被破解,如今已经很少再使用,其余四种分组模式各有千秋。
但极力推荐CBC模式和CTR模式,尤其是CTR模式,不需要填充,代码实现起来很方便。而且加密和解密的方法是一样的,并且可以实现并发分组,效率高,安全性也有保障
参考文章:
1,对称加密算法常用的五种分组模式(ECB/CBC/CFB/OFB/CTR)
关于作者
- GitHub:https://github.com/ForTheDevelopers
- 掘金:https://juejin.cn/user/1204720472953022/posts
- CSDN:https://blog.csdn.net/ForTheDevelopers
- segmentfault:https://segmentfault.com/u/for_the_developers
联系作者
- 微信号:ForTheDeveloper
- 公众号:ForTheDevelopers
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。