本节摘要:侧信道攻击不攻击算法,攻击算法的载体:一次模幂的耗时差、一个芯片的功耗波形、一条总线的电磁泄漏、一块缓存的热点分布,都可能在数学不破一寸的情况下交出密钥。本节沿时间、功耗、电磁、缓存、故障五条信道复盘经典战役,并给出恒定时间与掩蔽两条工程防线。
1995 年,密码学家保罗·科赫(Paul Kocher)提出一个让整个行业失眠的观察:RSA 的模幂运算按"平方-乘法"逐位处理私钥——遇到 1 做一次乘法,遇到 0 只做平方。乘法比平方慢,于是整个运算的总耗时与私钥的比特构成相关。远程测量服务器解密若干精心构造报文的响应时间,统计学足够的话,可以一位一位地把私钥磨出来。算法没有任何弱点——弱点是时间本身。
这一观察开创的侧信道(side-channel)攻击,本质是承认一条被忽略的信息通路:任何涉及密钥的计算都会在物理世界留下涟漪,而涟漪的形状与密钥相关。2.2 节恩尼格玛的教训在这里以物理形态复活:敌手不需要正面强攻密码机器,机器的使用痕迹会替他开门。

侧信道的对策不是更强的数学,而是让物理痕迹与密钥解耦。软件侧的第一律是恒定时间编程:秘密相关的分支(if k_i == 1)与按秘密索引的查表(S 盒直查)一律禁止,改用无分支位运算与"查全表再选"的模式;对概率运算(RSA 的盲化、ECDSA 的 nonce 掩蔽)注入随机性,让每次执行的功耗互不相同,DPA 的统计对齐失去锚点。硬件侧有掩蔽逻辑、双轨电路与安全元件隔离。验收同样工业化:时间分析仪与 TVLA 统计测试已是密码库发布流程的固定工序。
一个最小的时间泄露演示,直观感受"分支即泄密":
import time def leaky_modexp(base, exp, mod): # 反面教材:耗时暴露 exp 的比特构成 result, total = 1, 0 while exp > 0: if exp & 1: # 分支依赖秘密比特 result = result * base % mod total += 1 # 乘法次数即比特 1 的个数 base = base * base % mod exp >>= 1 return result, total result, mults = leaky_modexp(1234567, 0b10110101, 999999937) print("乘法次数 =", mults, "-> 攻击者据此统计出密钥中 1 的分布") # 防御思路:固定步数、无条件执行乘法再按位选择、或随机盲化——即恒定时间实现
💡 关键直觉:侧信道把"安全"从数学命题拉回物理命题。审一份密码实现的代码,先别看算法写对没有——先看有没有任何一行的执行时长、内存地址或功耗模式取决于秘密。
第一步,静态审查三类高危写法:以秘密比特为条件的分支、以秘密字节为下标的查表、以秘密值为循环次数的循环。命中任何一条,就该考虑恒定时间的替代写法——无分支的位选择、查全表后按掩码选取、固定轮次的循环。
第二步,工具测量:统计式的时间测试框架可以自动对比两组输入的耗时分布是否可区分;基于硬件性能计数器的缓存观察工具能指出哪些缓存行被秘密相关的访问触碰过。
第三步,选库与升级:优先选用把恒定时间写进设计目标的密码库,跟踪其安全通告中的侧信道修复记录;嵌入式场景优先考虑带硬件加速与屏蔽的芯片方案。
最后一步,写进流程:侧信道体检应与模糊测试一样进入持续集成,而不是发布前的最后一次人工抽查。7.1 节说过攻击者早已不与数学正面作战,防御者也必须把物理层列入常规审计,而不是等示波器上门才补课。
电磁侧信道的资历比集成电路还老。20 世纪中叶,交叠双方都为打字机、电传机与显示设备的电磁辐射建立了庞大的防护与侦收体系,"风暴"防护标准正是那段时期的产物;1985 年,荷兰研究者范艾克用公开资料演示:用数千美元的设备在街上还原附近显示器的屏幕内容,这条技术路线从此以他的名字命名。把这段历史与本章的缓存攻击放在一起看,会得到一个朴素的结论:泄漏的物理形态一直在变(辐射、功耗、时序、缓存),泄漏的原理从未变过——任何与秘密相关的物理量,都是可以测量的信号。
物理缝隙可以补,数学地基若被动摇呢?下一节面对全书最大的变量:当量子计算机让 Shor 算法跑起来,RSA 与 ECC 的地基同时松动——迁移已经开始。