简单功耗分析(SPA)概念与示例

说到简单功耗分析,大家第一反应是什么?

我刚开始接触侧信道时,觉得这名字挺唬人。后来做了几个项目才发现,SPA说白了就是——看波形猜算法。

你拿着示波器,探针怼在芯片电源引脚上,然后盯着屏幕上的电流起伏。嗯,这里跳了一下,那里顿了一下。如果你能直接看出芯片在做什么操作,恭喜你,你已经会了最基本的SPA。

什么是SPA?

简单功耗分析,全称 Simple Power Analysis。它利用的是芯片在执行不同指令时,功耗消耗会不一样这个物理特性。

举个例子。

芯片算乘法的时候,电流会飙高。算加法的时候,电流就平缓。做条件跳转的时候,波形会突然凹下去一块。你想想看,如果我能把整个程序的执行流程从一条功耗曲线上还原出来,那密钥还有什么秘密可言?

核心思想:一条功耗曲线 = 一次完整的算法执行过程。SPA的目标就是直接从这条曲线上读取关键信息。

我在项目中遇到过一种情况。客户说他的加密芯片安全,所有数据都是密文传输。我拿过来,先没做复杂的统计分析,就单纯看了一下芯片上电后的功耗波形。结果发现——密钥分量的加载有明显的节奏差异。高位的比特对应的波形电压偏高,低位偏低。这不就等于明文送给我了吗?

SPA与DPA有什么区别?

对比维度 SPA(简单功耗分析) DPA(差分功耗分析)
需要的曲线数量 1条或少量 通常上千条
分析方法 肉眼观察 + 经验判断 统计假设检验
依赖知识 熟悉算法执行流程 知道算法结构即可
抗噪声能力 弱(受噪声影响大) 强(平均效应)
典型场景 密钥分量的非平衡编码 破解即使有掩码的算法

这张表你可能看过很多次了。但我必须强调一点:SPA的攻击门槛其实比DPA高。为什么?因为你需要真的看懂波形。这不是跑个脚本就能出结果的事情。

我见过不少刚入行的同学,拿到SPA波形后不知道看哪里。嗯,这很正常。我自己刚开始也这样。关键是——你得先知道正常波形长什么样,才能看出哪个地方不对劲。

SPA在实际攻击中的应用

举两个最常见的例子。

场景一:RSA中的平方-乘算法的密钥提取

很多低成本的RSA实现,用的还是经典的平方-乘算法。算法逻辑大概是这样:

for each bit in key:
    square()
    if bit == 1:
        multiply()

实际执行的时候,如果密钥当前比特是1,功耗曲线上会出现一个额外的乘操作。你只要找到波形里多出来的那团凸起——凸起对应的就是比特1,没有凸起就是比特0。

就这么简单。

⚠️ 注意:这不是假设场景。我在实验室里亲自复现过。拿一个8位单片机跑的RSA,采样率100MS/s,示波器带宽50MHz,出来的波形清晰到可以直接数比特。密钥是1024位的,数完不到半小时。

场景二:AES S盒查找的指令差异

很多软件实现AES时,会用查表法替换S盒。如果S盒的数据在内存中排列不均衡,或者查表指令的执行时间因输入不同而不同,功耗波形上就会出现可观察的差异。

比如下面这个极简的例子:

// 简化AES S盒查找(非平衡实现)
uint8_t sbox[256];
uint8_t out = sbox[input];

如果编译器把这行代码编译成了条件加载或间接分支,输入值的不同会导致微架构层面的功耗差异。这种差异用肉眼可能难以分辨,但结合一点小技巧——比如对齐波形后看局部放大图——你就能把每个S盒输入猜出来。

有同学会问:现在芯片不都有掩码保护了吗?

是的,很多高级芯片有。但我发现很多产品经理以为“上了掩码就万事大吉”。你猜怎么着?掩码只防护DPA,对SPA几乎无效。因为SPA看的是操作顺序和宏观结构,掩码改不了这些东西。这是我很多年前踩过的坑,分享给你们。

SPA攻击的防御措施

怎么防?这里分享一下我个人比较认可的做法。

  • 恒功率设计:芯片不管执行什么操作,消耗的功率都一样。比如差分逻辑电路。缺点是面积和功耗会翻倍。
  • 随机插入伪操作:在算法流程里随机插入空循环或冗余计算,打乱波形的时间对齐。我看过一个开源的AES实现,插入了最多15%的伪操作,SPA的有效性直接降到20%以下。
  • 密钥分量采用平衡编码:比如双轨编码。密钥分量0和1在波形上无法区分。我曾经测试过一个客户的双轨设计,SPA攻击时间从半小时拖到了两周——不是说不可以,但投入产出比让攻击者放弃了。

💡 一个小技巧:如果你现在手头就有芯片在做SPA测试,我建议你先把示波器的采样率调到芯片主频的5倍以上。大多数情况下,SPA分辨率不够的问题都是采样率偏低造成的。

本章知识体系

下面这张SVG图,从原理、攻击手段到防御措施,把SPA的核心链路串起来了。

简单功耗分析(SPA)知识体系结构图 简单功耗分析(SPA)知识体系结构 物理层:功耗泄露 观测层:示波器采样功耗波形 分析方法:肉眼观察 + 经验判读 RSA 平方-乘算法 通过额外乘法暴露密钥比特 AES S盒查找差异 指令结构差异导致波形差异 密钥分量失衡编码 高位/低位功耗差异明显 防御措施:恒功率 / 伪操作 / 平衡编码

一些实践建议

我自己带团队做侧信道测试时,给新人定了一个入门流程。你如果刚开始学SPA,可以参考一下:

  1. 先不要看波形。先把算法的伪代码背下来。知道哪一步会做什么操作,才能预测波形的形态。
  2. 抓一条标量乘法的完整波形。不需要精确破解,先练习区分平方操作和乘操作的功耗差异。
  3. 做一次简单的密钥分量对比。把密钥设置成全0和全1,看看波形有没有肉眼可见的幅度差异。
  4. 尝试人工标注波形。从波形里挑出条件分支操作对应的片段,比对代码结构。
  5. 最后,再尝试一次完整的密钥恢复——用你标注的比特序列推导出密钥。

📌 个人习惯:我每次做SPA分析前,都会在示波器上打开持续采集的余晖模式。这样能看到所有波形的叠加效果。如果有重复的时序抖动,余晖模式会让时序稳定的部分看起来更亮,异常点则发暗。这一招帮我发现了至少3次芯片的弱点设计。

你需要记住的

  • SPA的核心是:一条波形看全局。不需要多条曲线做统计,代价是你得真的看懂这条波形。
  • SPA对算法流程的依赖很大。如果你知道算法实现的结构,SPA就是降维打击。
  • 防御SPA的关键是破坏波形的可读性——让每条曲线都长得差不多,攻击者就难以提取信息。