一、可用的对称密钥算法-AES-128/AES-256/ChaCha20
对称密钥算法 | 安全强度(位) | 现在能否使用 | 发布日期 | 密钥长度(位) | 数据分块(位) | 计算性能(CPB) |
---|---|---|---|---|---|---|
分组算法-DES | - | 退役 | 1977 | 56 | 64 | - |
序列算法-RC2 | - | 退役 | 1987 | 8~1024 | - | - |
序列算法-RC4 | - | 退役 | 1987 | 40~2048 | - | - |
分组算法-3DES | <80 | 遗留 | 1995 | 168 | 64 | - |
分组算法-Camellia | ||||||
Camellia-128 | 128 | 现行 | 2000 | 128 | 128 | - |
Camellia-192 | 192 | 现行 | 2000 | 192 | 128 | - |
Camellia-256 | 256 | 现行 | 2000 | 256 | 128 | - |
分组算法-AES | ||||||
AES-128 | 128 | 现行 | 1998 | 128 | 128 | 0.48 |
AES-192 | 192 | 现行 | 1998 | 192 | 128 | 0.42 |
AES-256 | 256 | 现行 | 1998 | 256 | 128 | 0.67 |
序列算法-ChaCha20 | 256 | 现行 | 2008 | 256 | - | - |
其中,计算性能参考的是 ECRYPT 在 2020 年 7 月对较长数据的性能基准测试结果
我们前面讲过,为了能够处理任意大小的数据,并且输出结果长度固定,单向散列函数需要对数据进行分组,然后按数据组进行运算,在对称密钥算法里,因为输出结果的长度没有限制,对数据的处理方式也就有了更多的想象空间
如果我们从数据是否分组这个角度考虑,有两种处理方式:
- 分组算法:进行数据分组,然后按数据组进行运算
- 序列算法:不进行数据分组,按原始数据长度进行运算
序列算法的基本思路,就是从对称密钥里推导出一段和明文长度相同的密钥序列,然后和明文进行异或运算得到密文,反之和密文进行异或运算得到明文
一般来说,密钥序列的推导和异或运算都是快速的运算,所以,序列算法通常被认为是更高效的算法,比如说,在类似的条件下,相同安全强度的对称密钥,ChaCha20 算法要比 AES 算法快四到六倍,比 Camellia 算法快近十倍,如果你有关注过浏览器底层技术细节,你可能会注意到,ChaCha20 是现代主流浏览器优先选择的加密算法
由于不需要数据分组,序列算法的安全性主要取决于密钥序列的推导算法,而不用考虑数据分组带来的种种陷阱,但分组算法的安全性,除了算法本身外,还取决于数据分组策略
二、分组算法
一个典型的分组算法,一般由三部分组成,数据分组、分组运算和链接模式
1、数据分组
以 AES 为例,能够处理的数据块大小是 128 位,那么,明文就需要被分割成一个或者多个 128 位的数据块,如果不能整分,还需将最后一个分组数据补齐成 128 位,这些分组数据的运算结果组合起来就是密文,解密时,执行相反操作
2、分组运算
把每一个明文分组通过加密函数,转换成密文分组
3、链接模式
把上一个分组运算和当前分组运算链接起来,这样能够保证即便明文里包含相同的分组数据,分组运算的结果也会不同,但是第一个分组运算并没有上一个分组运算可以使用,这时候,我们就需要引入一个初始化的数据,来承担“上一个分组运算”向下链接的功能,我们一般称这个初始化数据为初始化向量
3.1、初始化向量-一个对称密钥的生命周期,初始化向量不能重复
一般来说,一个对称密钥要使用多次,对多个明文进行加密运算,如果存在第一个数据块(上图的明文分组1)相同的两个明文,并且又使用了相同的初始化向量,那么第一个分组运算结果(上图的密文分组1)也会相同,攻击者就可以根据密文是否相同来猜测、寻找明文,如此就破坏了数据的保密性,但大多时候我们都没办法确定多个明文会不会有重复数据,甚至重复数据会不会是第一个数据块,所以,我们只能在初始化向量这一个因素上想办法,也就是在一个对称密钥的生命周期里,初始化向量不能重复,这是使用对称密钥算法的第一个要求
3.2、对称密钥的使用次数
在一个对称密钥的生命周期里,初始化向量不能重复,由于初始化向量的长度固定,也就意味着初始化向量的个数是有限制的,以 AES 为例,一个 128 位的初始化向量,最多有 2^ 128 个不重复的选择,进一步讲,AES 的一个密钥最多能使用 2^ 128 次,这是一个巨大的数字,一般的应用程序也没什么机会有这么多次加密运算,但一些其他因素也会限制密钥的使用次数,很多限制因素的叠加,就会使得密钥的使用次数远低于初始化向量的许可数目,所以,我们心里一定要知道,密钥是有使用次数限制的,并且要有检查密钥使用次数限制的习惯