3DES 用三把 DES 密钥做三次运算,每把 56 位有效强度,加起来是 168 位。但所有资料都说它的有效强度约 112 位。中间少掉的 56 位去哪了?答案是一个叫「中间相遇攻击」的方法,它让三密钥的 3DES 实际强度打了折。
先看 3DES 的运算结构
3DES 的全称是 Triple DES,也写作 DES-EDE3。它把 24 字节密钥拆成 K1、K2、K3 三把 8 字节子密钥,对数据依次执行三个操作:
密文 = E(K3, D(K2, E(K1, 明文)))
注意中间那一步是解密(D),不是加密。这个「加密—解密—加密」的组合(EDE)有一个巧妙的作用:如果 K1 = K2 = K3,那么中间的解密会把第一次加密的结果还原,整个运算退化回一次普通的 DES。这让 3DES 可以兼容用单 DES 加密的历史数据——把三把密钥设成相同即可。
如果三把密钥都是随机的,且都提供 56 位强度,按简单乘法就是 168 位。但攻击者不会老老实实地穷举 168 位。
中间相遇攻击怎么省力
中间相遇攻击(Meet-in-the-Middle)的思路是:把密钥空间从中间劈开,两头分别穷举,再在中间对撞。
对 3DES 来说,攻击者可以这样做:把 168 位的密钥空间拆成「K1」和「K2 + K3」两半,或者更实际的拆法是把 E(K1) 和 E(K3) 分开处理。
具体做法是:对第一层 E(K1, P) 穷举所有可能的 K1,把结果存进一张表;对第三层反向推导 D(K3, C),穷举所有可能的 K3,每算出一个值就去表里查。只要两边的值相等,就找到了一组候选的 (K1, K3)。
这个方法的代价是:需要约 2^56 的存储空间和约 2^112 的计算量。关键就在于这个 2^112——它比 168 位小得多,因为攻击者不需要同时穷举三把密钥。
所以 3DES 的实际强度被记为约 112 位,而不是 168 位。
为什么是 112 而不是 56
有人会问:既然攻击者只要穷举 K1 和 K3,那强度是不是只有 112 位?为什么不是更低的数字?
因为攻击者仍然需要穷举两把独立的密钥(K1 和 K3),这两部分各 56 位,合起来 112 位。K2 在中间相遇的过程中可以通过已知的中间值反推出来,所以不需要单独穷举它。这就是「少掉的那 56 位」——它对应的是 K2 的空间。
所以准确的说法是:三密钥 3DES 的强度约为 2^112 次运算。这比单 DES 的 2^56 强了 2^56 倍,是一个巨大的提升;但比名义上的 2^168 弱,因为中间相遇攻击削掉了三分之一的强度。
2-key 3DES 的情况
如果为了节省密钥长度,把 K3 设成和 K1 相同(即使用 K1、K2、K1 这样的 16 字节密钥),强度会进一步下降。
这种变体的有效强度约为 80 位。原因类似:攻击者只需要穷举 K1 和 K2,中间相遇攻击的代价相应降低。
80 位在今天已经不够安全——按每秒 2^40 次尝试的算力估算,穷举 2^80 大约需要 2^40 秒,也就是三万多年;但如果攻击者有专用硬件或者能利用更大的并行度,这个时间会被显著压缩。相比之下,112 位仍然有充足的余量。
所以如果必须使用 3DES,应该使用标准的三密钥形式。有些实现只接受 24 字节密钥,有些允许 16 字节;遇到 16 字节密钥的旧系统时,可以把它拼成 K1 + K2 + K1 的 24 字节形式再交给标准实现。
这对选型意味着什么
从 3DES 的强度分析可以总结出一条经验:名义密钥长度不等于实际安全强度。
一个算法的有效强度,取决于已知的最优攻击方法。设计者按理想情况推算出的位数,可能因为攻击方法的进步而打折扣。所以评估算法时应该看它当前被公认的有效强度,而不是把各部分强度简单相加。
同样的逻辑也适用于其他地方。比如哈希函数的碰撞强度是输出位数的一半(生日攻击),而不是输出位数本身。这些「打折」都来自攻击者可以选择更聪明的路径。
检查清单
- 3DES 的运算是「用 K1 加密、用 K2 解密、用 K3 加密」的 EDE 结构
- 名义强度是 168 位,但中间相遇攻击把它降到约 112 位
- 少掉的 56 位对应 K2,它可以在中间相遇过程中被反推,不需要单独穷举
- 2-key 形式(K1、K2、K1)的强度约为 80 位,余量不足
- 必须使用 3DES 时应采用标准 24 字节三密钥形式
- 评估算法要看公认的有效强度,而不是各部分强度的简单相加