本节摘要:讨论"某算法是否安全"之前必须先回答"敌手能拿到什么"。本节立起唯密文、已知明文、选择明文、选择密文四档攻击模型,给出暴力穷举的成本算术,概览线性、差分、生日等分析方法家族,并说明协议层与实现层攻击为何在实战中的产量远高于算法层。
同一段密文,落在不同能力的攻击者手里是不同的问题。密码分析的第一步不是找弱点,而是约定敌手的接口——四档模型从弱到强:
| 模型 | 敌手能力 | 典型场景 | 现代安全口径 |
|---|---|---|---|
| 唯密文 COA | 只见密文 | 历史战场窃听 | 仅是底线,无现实意义 |
| 已知明文 KPA | 有若干明密文对 | crib、格式化报文 | 古典密码在此全军覆没 |
| 选择明文 CPA | 可指定加密输入 | 可预测字段、回显 | 对称加密最低要求 |
| 选择密文 CCA | 可指定解密请求 | 填充预言机、解密服务 | 认证加密的设计目标 |
暴力穷举的账很好算:n 位密钥平均要试 2ⁿ⁻¹ 次。可参照的标尺有三个:全球算力(年运算量远低于 2¹⁰⁰)、物理极限(翻转一个比特的最低能耗约 2.85×10⁻²¹ 焦耳,按此折算穷举 2¹²⁸ 需要的电量以恒星产能计)、以及 3.2 节 Deep Crack 的实证(56 位在 1998 年值 56 小时)。结论直接:128 位以下不再够格,256 位在 Grover 算法之外是安全的——这条线决定了 AES 三档密钥与哈希摘要长度的当代口径。
对结构本身的攻击则有四个流派:差分分析(Biham 与 Shamir 1990 年公开,跟踪明文差在轮函数中的传播概率,DES 的 S 盒当年正是被它"后验"出设计精妙);线性分析(松井充 1993 年,找明文、密文、密钥比特间的概率性线性近似,攻 DES 需约 2⁴³ 个已知明文);生日攻击(对哈希与分组模式的通用平方根折扣,5.1 节已算过账);以及各类解析攻击(王晓云对 MD5/SHA-1 的差分路径即属此类)。值得注意的是:这四派攻 AES、SHA-2 十余年,战绩只是把安全边界磨薄几个比特——理论与实战之间隔着一个工程宇宙。
实战攻击的高产区在算法之外。协议层的重放(旧报文再次投递)、降级(诱使双方用弱版本协商,Logjam/POODLE)、中间人(无认证的协商被拆成两次会话)、反射(让协议消息打回发起方自答)——6.1 节的 TLS 事故清单几乎全部属于这一层。实现层的产量更高:随机数缺陷是冠军常客(2008 年 Debian 打包误删熵源代码, OpenSSL 密钥空间塌缩到三万出头,全网 SSH 密钥一夜可枚举;4.5 节安卓比特币钱包的重复 k 同属此类),此外还有硬编码密钥、越界读内存(Heartbleed)、以及下一节的物理侧信道。
⚠️ 常见误解:"先自己实现一个,以后再换库"。自实现的风险不是写错某一行,而是你无法知道自己错在哪——审计过的库背后是二十年事故数据库,自实现背后只有自信。
用 Python 把两条经典账算成可查询的数字:
import math def brute_force_years(bits, tries_per_sec=1e12): """以每秒 1 万亿次尝试折算穷举平均耗时(年)""" return 2 ** (bits - 1) / tries_per_sec / 3600 / 24 / 365 for bits in (56, 64, 128, 256): print(f"{bits:3d} 位密钥:约 {brute_force_years(bits):.2e} 年") def birthday_bits(hash_bits): """生日折扣后找碰撞的等效强度""" return hash_bits / 2 print("SHA-256 找碰撞等效强度:", birthday_bits(256), "位") # 128 print("n=2^40 个输入中至少一对同摘要的概率:约", 1 - math.exp(-2**40 * 2**40 / 2**256))
场景一,攻击者截获一段无格式的加密存档——唯密文档。场景二,邮件系统主题栏格式固定、正文可猜测——已知明文档。场景三,攻击者能让服务器给自己生成的 Cookie 加密——选择明文档。场景四,解密服务对任意输入返回解密结果或错误信息——选择密文档,填充预言机的温床。给每个场景配防御口径:前三者至少需要抗选择明文的对称方案,第四者必须上认证加密。把日常系统对号入座一次,敌手模型就不再是教科书名词。
模型与流派立好了,下一节看攻击者最锋利的那把刀:当数学不肯让步,就去测量电——侧信道攻击如何把示波器变成钥匙复制机。