3、侧信道泄露原理:物理泄露来源(功耗、电磁、时序、缓存)、数据依赖与操作依赖
侧信道攻击之所以能够奏效,其根本原因在于密码设备在运行过程中,其物理行为并非“恒定不变”,而是与内部处理的数据和执行的指令存在强相关性。这种相关性通过功耗、电磁辐射、执行时间以及缓存状态等物理信道被“泄露”出来。理解这些泄露的来源及其背后的依赖关系,是进行有效功耗分析与电磁分析的前提。本章将深入剖析物理泄露的四大来源,并重点区分“数据依赖”与“操作依赖”这两种核心泄露模型,为后续的统计分析与密钥恢复奠定理论基础。
上图清晰地展示了密码设备作为泄露源的中心地位,以及四大物理信道(功耗、电磁、时序、缓存)与两种依赖模型(数据依赖、操作依赖)之间的逻辑关系。在实际测量中,功耗与电磁信号通常表现为模拟量,主要反映数据依赖;而时序与缓存状态则更多表现为离散事件,主要反映操作依赖。但需要强调的是,这种对应并非,例如功耗曲线中的某些尖峰也可能由特定操作(如乘法指令)引起,而缓存失效的时序差异最终也会通过功耗或电磁信号体现出来。因此,分析人员需要综合多种信号,才能构建完整的泄露模型。
3.1 物理泄露的四大来源
物理泄露的本质是信息论中的“侧信道”——即密码算法在硬件实现时,其内部状态变化通过物理量变化被外部感知。下面逐一剖析四大来源的微观机理。
3.1.1 功耗泄露:CMOS电路的“数据指纹”
现代数字电路几乎全部基于CMOS工艺。CMOS电路在逻辑状态翻转时,会对负载电容进行充放电,产生瞬态电流,即动态功耗。动态功耗的大小与翻转的电容负载、电源电压以及翻转频率成正比。更重要的是,翻转的位数与具体数据值直接相关。例如,一个8位数据总线从0x55(01010101)变为0xAA(10101010)时,所有8位都发生翻转,产生的功耗尖峰远大于从0x55变为0x54(仅1位翻转)的情况。这种“汉明距离”或“汉明重量”与功耗的线性关系,正是功耗分析攻击(如CPA)的物理基础。
核心原理:功耗泄露主要来源于动态功耗(翻转电流)和少量静态功耗(漏电流)。对于密码芯片,S盒查找表、寄存器更新、总线传输等操作都会产生与数据相关的功耗变化。测量时通常使用串联小电阻(如1Ω~50Ω)或电流探头,通过示波器以高采样率(≥1GSa/s)记录功耗轨迹。
3.1.2 电磁泄露:近场辐射的“天线效应”
任何载有瞬态电流的导体都会在其周围产生变化的磁场。芯片内部的金属互连线、电源网络、甚至封装引脚都构成了微型天线,向空间辐射电磁波。电磁泄露的强度与电流变化率(di/dt)成正比,因此高频成分丰富的信号(如时钟沿、总线翻转)辐射更强。与功耗测量需要物理接触不同,电磁测量可以使用近场探头(如磁场探头)在芯片表面上方非接触式采集信号,这为攻击者提供了更大的便利性,也使得防护更加困难。
电磁泄露的空间分布不均匀,不同位置的探头采集到的信号成分不同。例如,靠近S盒模块的位置,电磁信号中数据依赖成分更强;而靠近时钟树的位置,则主要是固定频率的时钟谐波。因此,电磁分析通常需要进行“空间扫描”,找到泄露最强的热点位置。
3.1.3 时序泄露:执行路径的“时间差”
时序泄露是指设备执行密码操作所需的时间随输入数据或密钥变化而变化。这种差异可能来源于:
- 算法级:如RSA中的模幂运算,根据指数位是0还是1,执行不同的操作序列(平方或平方+乘法),导致总执行时间与密钥的汉明重量相关。
- 指令级:如某些MCU的乘法指令执行周期数固定,但若使用软件查表法实现S盒,则查表时间可能因缓存命中与否而不同。
- 优化级:编译器或硬件优化(如分支预测、乱序执行)可能导致特定数据路径更快完成。
时序攻击(如计时攻击)通过精确测量多次操作的执行时间,利用统计方法推断密钥。虽然现代密码库大多已实现“常数时间”代码,但在嵌入式裸机环境中,时序泄露依然普遍存在。
3.1.4 缓存泄露:微架构的“共享资源”
缓存泄露是CPU微架构侧信道的一种,主要存在于运行通用操作系统(如Linux)的处理器中。当密码软件访问S盒或查表数据时,若数据不在缓存中(Cache Miss),则需要从主存加载,耗时较长;若在缓存中(Cache Hit),则耗时极短。攻击者通过填充缓存、监测自己的访问时间,可以判断受害者是否访问了特定地址。典型攻击包括Prime+Probe、Flush+Reload等。缓存泄露不仅泄露了访问模式,还能间接泄露数据值(因为访问的地址往往由数据决定)。
| 泄露来源 | 物理载体 | 主要依赖类型 | 典型测量方式 | 攻击模型 |
|---|---|---|---|---|
| 功耗 | 电流/电压 | 数据依赖 | 串联电阻、电流探头 | SPA/DPA/CPA |
| 电磁 | 磁场/电场 | 数据依赖+操作依赖 | 近场探头、频谱分析 | EMA/模板攻击 |
| 时序 | 时间 | 操作依赖 | 高精度计时器 | 计时攻击 |
| 缓存 | Cache状态 | 操作依赖+数据依赖 | 时间测量、性能计数器 | Prime+Probe |
3.2 数据依赖与操作依赖的深度辨析
理解这两种依赖关系是选择攻击策略的关键。简单来说,数据依赖关注“处理了什么值”,操作依赖关注“执行了什么操作”。
3.2.1 数据依赖:数值的“汉明重量”与“汉明距离”
数据依赖泄露是指物理量(如功耗)的大小与中间值(如S盒输出)的某种数学特征相关。最常用的两个模型是:
- 汉明重量模型(HW):假设功耗与中间值中“1”的个数成正比。适用于寄存器或总线在静态状态下被读取时,其功耗与存储的数值相关。
- 汉明距离模型(HD):假设功耗与前后两个状态之间发生翻转的位数成正比。适用于寄存器或总线在动态更新时,其功耗与新旧值的差异相关。
例如,在AES算法的第1轮中,S盒输出值s与轮密钥k异或后存入寄存器。若攻击者已知明文p,则中间值s = Sbox(p ^ k)。攻击者可以猜测一个密钥字节k_guess,计算对应的s,然后计算s的汉明重量,并与实际测得的功耗轨迹做相关系数分析。相关系数最高的k_guess即为正确密钥。这就是相关功耗分析(CPA)的核心思想。
实战经验:在实际测量中,功耗轨迹往往包含大量噪声。为了提取微弱的数据依赖信号,通常需要采集上千条甚至上万条功耗轨迹进行平均处理,以消除随机噪声。同时,选择泄露点(即功耗轨迹上与S盒输出时刻对应的采样点)至关重要,通常通过“差分功耗分析(DPA)”的峰值位置来确定。
3.2.2 操作依赖:指令的“能量指纹”
操作依赖泄露是指物理量(如功耗或电磁)的波形形状与执行的特定指令或操作相关。例如,一条乘法指令(MUL)在MCU上执行时,其功耗波形与一条加法指令(ADD)明显不同,因为乘法器内部的逻辑翻转活动远多于加法器。简单功耗分析(SPA)正是通过直接观察单条功耗轨迹的形态,来识别算法中的关键操作。例如,在RSA实现中,如果模乘和模平方的功耗波形差异明显,攻击者可以直接从轨迹中读出密钥的二进制位序列。
操作依赖不仅体现在指令级,还体现在算法结构级。例如,AES的轮函数包含SubBytes、ShiftRows、MixColumns、AddRoundKey四个步骤,每一步的功耗特征不同。通过SPA可以定位每一轮的起始位置,从而辅助DPA攻击。
3.2.3 两种依赖的对比与综合应用
下表总结了两种依赖的核心区别:
| 维度 | 数据依赖 | 操作依赖 |
|---|---|---|
| 关注对象 | 数据值(0/1序列) | 操作类型(指令/步骤) |
| 泄露特征 | 幅度大小(模拟量) | 波形形状/时序位置 |
| 典型攻击 | DPA/CPA | SPA/模板攻击 |
| 抗干扰能力 | 需统计平均 | 单条轨迹即可 |
| 防护难点 | 掩码(Masking) | 隐藏(Hiding)/常数时间 |
在实际攻击中,两种依赖往往同时存在。例如,一条LOAD指令从内存加载S盒数据,其功耗既包含LOAD操作本身的固定特征(操作依赖),也包含加载的数据值对应的总线翻转(数据依赖)。高级攻击技术(如模板攻击)会同时利用这两种依赖,为每个可能的操作和数据值建立多维高斯模板,实现高精度的单轨迹密钥恢复。
3.3 案例拆解:针对AES-128第一轮的CPA攻击
为了将上述理论付诸实践,我们以一个标准的AES-128加密过程为例,演示如何利用功耗的数据依赖恢复第一轮轮密钥。
背景与目标:目标设备为运行AES-128的8位智能卡(如ATmega163)。攻击者拥有与设备的物理接触权限,可以控制明文输入,并采集加密过程中的功耗轨迹。目标是恢复128位轮密钥中的第一个字节K[0]。
初始现象与关键参数:
- 采样率:2 GSa/s,记录完整一轮加密(约2000个采样点)。
- 明文:随机生成1000个不同的明文块。
- 功耗轨迹:每条轨迹为
T[1..2000]的电压数组。 - 泄露模型:汉明重量模型,中间值
V = Sbox(plaintext[0] ^ K_guess)。
分析判断过程:
- 数据预处理:将1000条轨迹对齐(触发点对齐),并去除直流偏置。
- 选择泄露点:通过DPA方法,计算每个采样点上的“平均功耗差”(即密钥猜测为0xFF和0x00时的功耗差),找到差值最大的采样点索引
t_leak。该点通常对应S盒输出写入寄存器的时刻。 - 计算假设功耗:对于每个密钥猜测
K_guess(0~255),计算1000个明文对应的中间值V_i,并计算其汉明重量HW(V_i)。 - 计算相关系数:使用皮尔逊相关系数计算
HW(V)与实测功耗T[t_leak]之间的相关性ρ。 - 密钥判定:正确的
K_guess将产生最大的ρ值(通常>0.5),而错误猜测的ρ值接近0。
实际操作步骤与结果:
# 伪代码示例(Python风格)
for K_guess in range(256):
hw = []
for pt in plaintexts:
v = sbox[pt[0] ^ K_guess]
hw.append(popcount(v))
rho = corrcoef(hw, traces[:, t_leak])
if rho > best_rho:
best_rho = rho
best_key = K_guess
print("恢复的密钥字节:", best_key)
执行后,正确密钥K[0]=0x2B(假设)的相关系数ρ=0.62,而其他255个猜测的ρ值均低于0.1。攻击成功。
风险与代价:该攻击需要约1000条轨迹,耗时约2分钟(含计算)。若设备有功耗噪声抑制(如时钟随机化),则需增加轨迹数量至数万条,或改用更精细的泄露模型(如HD模型)。
复盘经验:CPA攻击的成功率高度依赖于泄露点的准确选择。若t_leak选择偏差几个采样点,相关系数会显著下降。因此,建议先使用DPA进行全局扫描,确定泄露窗口,再进行CPA。
3.4 常见误区与总结复盘
在理解侧信道泄露原理时,初学者常陷入以下误区:
误区一:认为功耗泄露只与数据有关。实际上,操作依赖(如指令周期)同样会调制功耗波形。忽略操作依赖可能导致SPA失败,或CPA的泄露点定位错误。
误区二:混淆汉明重量与汉明距离。在寄存器更新场景中,若使用HW模型而实际泄露是HD模型,相关系数会大幅降低。必须根据电路结构选择合适的模型。
误区三:忽视电磁泄露的空间特性。电磁信号是矢量场,探头位置和方向对采集结果影响巨大。不做空间扫描就采集,可能错过最佳泄露点。
误区四:认为时序泄露只存在于软件实现。硬件加速器(如AES引擎)虽然执行时间固定,但其功耗或电磁信号中仍可能包含与数据相关的微时序差异(如毛刺位置),这属于“局部时序泄露”。
总结复盘:本章的核心在于建立“物理量-数据/操作-攻击模型”的映射关系。在实际评估中,建议遵循以下流程:
- 信号采集:使用高带宽示波器和低噪声探头,同步采集功耗/电磁信号。
- 泄露识别:通过SPA观察波形特征,通过DPA/CPA定位数据泄露点。
- 模型验证:对比HW/HD模型与实测数据的相关性,选择最优模型。
- 攻击实施:根据目标选择单轨迹攻击(SPA/模板)或多轨迹攻击(DPA/CPA)。
只有深刻理解泄露的物理根源,才能制定有效的防护策略(如掩码、隐藏、恒定时间实现),也才能在攻击测试中做到“知其然,更知其所以然”。