对称加密工作模式及填充方式
该文主要介绍对称加密工作模式及填充方式。
对称加密工作模式及填充方式
1. 工作模式1
1.1. 电子密码本(ECB)
最简单的加密模式即为电子密码本(Electronic codebook,ECB)模式。需要加密的消息按照块密码的块大小被分为数个块,并对每个块进行独立加密。
1.2. 密码块链接(CBC)
1976
年,IBM
发明了密码分组链接(CBC,Cipher-block chaining)模式。在 CBC
模式中,每个明文块先与前一个密文块进行异或后,再进行加密。在这种方法中,每个密文块都依赖于它前面的所有明文块。同时,为了保证每条消息的唯一性,在第一个块中需要使用初始化向量。
若第一个块的下标为 1
,则 CBC
模式的加密过程为
而其解密过程则为
\[\begin{aligned} P_{i} &= D_{K}(C_{i}) \oplus C_{i-1} \\ C_{0} &= IV \end{aligned}\]CBC
是最为常用的工作模式。它的主要缺点在于加密过程是串行的,无法被并行化,而且消息必须被填充到块大小的整数倍。解决后一个问题的一种方法是利用密文窃取。
注意在加密时,明文中的微小改变会导致其后的全部密文块发生改变,而在解密时,从两个邻接的密文块中即可得到一个明文块。因此,解密过程可以被并行化,而解密时,密文中一位的改变只会导致其对应的明文块完全改变和下一个明文块中对应位发生改变,不会影响到其它明文的内容。
1.3. 密文反馈(CFB)
密文反馈(CFB,Cipher feedback)模式类似于 CBC
,可以将块密码变为自同步的流密码;工作过程亦非常相似,CFB
的解密过程几乎就是颠倒的 CBC
的加密过程。
1.4. 输出反馈(OFB)
输出反馈模式(Output feedback, OFB)可以将块密码变成同步的流密码。它产生密钥流的块,然后将其与明文块进行异或,得到密文。与其它流密码一样,密文中一个位的翻转会使明文中同样位置的位也产生翻转。
由于 XOR
操作的对称性,加密和解密操作是完全相同的:
每个使用 OFB
的输出块与其前面所有的输出块相关,因此不能并行化处理。然而,由于明文和密文只在最终的异或过程中使用,因此可以事先对 IV
进行加密,最后并行的将明文或密文进行并行的异或处理。
1.5. 计数器模式(CTR)
注意:CTR模式(Counter mode,CM)也被称为ICM模式(Integer Counter Mode,整数计数模式)和SIC模式(Segmented Integer Counter)。
与 OFB
相似,CTR
将块密码变为流密码。它通过递增一个加密计数器以产生连续的密钥流,其中,计数器可以是任意保证长时间不产生重复输出的函数,但使用一个普通的计数器是最简单和最常见的做法。
1.6. 特点
模式 | 名称 | 优点 | 缺点 | 备注 |
---|---|---|---|---|
ECB模式 | Electronic CodeBook电子密码本模式 | 简单 快速 支持并行计算(加密、解密) | 明文中的重复排列会反映在密文中 通过删除、替换密文分组可以对明文进行操作 对包含某些比特错误的密文进行解密时,对应的分组会出错 不能抵御重放攻击 | 不推荐使用 |
CBC模式 | Cipher Block Charning密文分组链接模式 | 明文的重复排列不会反映在密文中 支持并行计算(仅解密) 能够解密任意密文分组 | 对包含某些错误比特的密文进行解密时,第一个分组的全部比特以及后一个分组的相应比特会出错 加密不支持并行计算 | 推荐使用 |
CFB模式 | Cipher-FeedBack密文反馈模式 | 不需要填充(padding) 支持并行计算(仅解密) 能够解密任意密文分组 | 加密不支持并行计算 对包含某些错误比特的密文进行解密时,第一个分组的全部比特以及后一个分组的相应比特会出错 不能抵御重放攻击 | 现在已不使用,推荐用CTR模式代替 |
OFB模式 | Output-FeedBack输出反馈模式 | 不需要填充(padding) 可事先进行加密、解密的准备 加密、解密使用相同结构 对包含某些错误比特的密文进行解密时,只有铭文中相应的比特会出错 | 不支持并行运算 主动攻击这反转密文分组中的某些比特时,明文分组中相对应的比特也会被反转 | 推荐使用CTR模式代替 |
CTR模式 | Counter计数器模式 | 不需要填充(padding) 可事先进行加密、解密的准备 加密、解密使用相同的结构 对包含某些错误比特的密文进行解密时,只有明文中相对应的比特会出错 支持并行计算(加密、解密) | 主动攻击者反转密文分组中的某些比特时,明文分组中对应的比特也会被反转 | 推荐使用 |
2. 填充方式2
2.1. 为什么需要填充
块密码只能对确定长度的数据块进行处理,而消息的长度通常是可变的。因此部分模式(即ECB和CBC)需要最后一块在加密前进行填充。
CFB
OFB
和 CTR
模式不需要对长度不为密码块大小整数倍的消息进行特别的处理。因为这些模式是通过对块密码的输出与明文进行异或工作的。最后一个明文块(可能是不完整的)与密钥流块的前几个字节异或后,产生了与该明文块大小相同的密文块。流密码的这个特性使得它们可以应用在需要密文和明文数据长度严格相等的场合,也可以应用在以流形式传输数据而不便于进行填充的场合。
2.2. 位填充
第一位为1
,补 0
至块大小。
这个方法可用于填充任何位长度的信息,而不限于整字节长度的信息。比如,一段 23 位的信息可填充 9 位以填满一个 32 位的块:
1
... | 1011 1001 1101 0100 0010 0111 0000 0000 |
2.3. 字节填充
字节填充可用于可编码为整数字节大小的信息。
2.3.1. ANSI X9.23
最后一个字节为需要填充的字节长度值
,其余位填充随机数(通常填充00
)。
例:下例中,块大小为 8 字节,需要填充 4 字节(以十六进制表示)。
1
... | DD DD DD DD DD DD DD DD | DD DD DD DD 00 00 00 04 |
2.3.2. ISO 10126
ISO 10126
(已撤回,2007 年)规定应在最后一个块的末尾用随机字节进行填充,并且填充边界应由最后一个字节指定。
示例:在下面的示例中,块大小为 8 个字节,需要填充 4 个字节。
1
... | DD DD DD DD DD DD DD DD | DD DD DD DD 81 A6 23 04 |
2.3.3. PKCS#5 和 PKCS#7
填充以整字节为单位。每个添加的字节的值是添加的字节数,即添加 N
个字节,每个字节的值均为 N
。添加的字节数将取决于消息需要扩展到的块边界。
PKCS#5
填充与 PKCS#7
填充相同,只是它仅针对使用 64
位(8 字节)块大小的分组密码进行定义。
例:下例中,块大小为 8 字节,需要填充 4 字节。
1
... | DD DD DD DD DD DD DD DD | DD DD DD DD 04 04 04 04 |
2.3.4. ISO/IEC 7816-4
与位填充方案相同,应用于 N
字节的纯文本。实际上,这意味着第一个字节是强制字节,值为 80
(十六进制),如果需要,后面是设置为 00
的 0
到 N-1
个字节,直到到达块的末尾。ISO/IEC 7816-4
本身是包含文件系统的智能卡的通信标准,本身不包含任何加密规范。
示例:在下面的示例中,块大小为 8 个字节,需要填充 4 个字节
1
... | DD DD DD DD DD DD DD DD | DD DD DD DD 80 00 00 00 |
2.4. 零填充
所有需要填充的字节都用 0
填充。
示例:在下面的示例中,块大小为 8 个字节,需要填充 4 个字节
1
... | DD DD DD DD DD DD DD DD | DD DD DD DD 00 00 00 00 |