阶段四侧信道防护 — 密码算法在数学上可能完美,但在物理实现中会通过功耗、时间、电磁辐射等"侧信道"泄露密钥信息。本课系统介绍侧信道攻击的原理和分类。
传统密码分析关注算法的数学结构,而侧信道攻击关注算法的物理实现。一个算法可能在数学上不可破,但其硬件实现可能通过物理观察变得完全透明。
运算时间与密钥相关的数据路径长度不同,导致执行时间泄露信息。
经典案例:RSA 平方-乘算法中,指数位为 1 时执行额外乘法,位为 0 时跳过。精确测量每次运算的时间可以逐位恢复指数。
CMOS 电路的动态功耗与数据翻转相关:
其中 α 是翻转概率,与处理的数据直接相关。
直接观察功耗轨迹的形状,识别运算模式。例如,RSA 乘法和平方的功耗模式不同。
统计方法:收集大量功耗轨迹,按密钥假设分组,通过统计差异验证正确密钥。即使单条轨迹的信号被噪声淹没,统计平均仍可提取密钥。
电流变化产生电磁辐射,可被近场探头捕获。比功耗测量更隐蔽,且可以定位到芯片的特定区域。
通过电压毛刺、激光、电磁脉冲等手段在运算中注入故障,利用错误结果推导密钥。
// sbox_power_model.v - S-Box 功耗模型(用于 DPA 仿真)
module sbox_power_model (
input wire [7:0] data_in,
input wire [7:0] key,
output wire [7:0] sbox_out,
output wire [3:0] hamming_weight, // 汉明重量
output wire [3:0] hamming_distance // 汉明距离
);
// 假设 S-Box 输出(简化为 XOR,实际应使用真实 S-Box)
assign sbox_out = data_in ^ key;
// 汉明重量:输出中1的个数
assign hamming_weight = sbox_out[0] + sbox_out[1] + sbox_out[2] + sbox_out[3] +
sbox_out[4] + sbox_out[5] + sbox_out[6] + sbox_out[7];
// 汉明距离:输入到输出翻转的位数
wire [7:0] xor_diff = data_in ^ sbox_out;
assign hamming_distance = xor_diff[0] + xor_diff[1] + xor_diff[2] + xor_diff[3] +
xor_diff[4] + xor_diff[5] + xor_diff[6] + xor_diff[7];
endmodule
| 层次 | 技术 | 对抗攻击 |
|---|---|---|
| 算法层 | 恒定时间算法 | 时间攻击 |
| 逻辑层 | 双轨预充电逻辑 | SPA/DPA |
| 架构层 | 掩码、随机化 | DPA/高阶DPA |
| 物理层 | 去耦电容、屏蔽 | EM/功耗探测 |
| 系统层 | 频率抖动、噪声注入 | 所有侧信道 |
1. 模拟 DPA 攻击:对 8 位 S-Box 收集 1000 条功耗轨迹(汉明重量模型 + 高斯噪声),使用差分分析恢复密钥字节。
2. 计算不同信噪比下 DPA 攻击所需的轨迹数量。
3. 实现一个功耗模拟器:对 AES SubBytes 操作,输出基于汉明重量的模拟功耗值。
4. 思考:为什么 DPA 比SPA 更强大?在什么条件下 SPA 就足够了?
你已理解侧信道攻击的完整分类和原理,掌握了 DPA 攻击流程和功耗模型。这是从"数学安全"到"物理安全"的关键认知!
获得徽章:👁️ SIDECHANNEL_EYE
推荐使用以下工具链进行课程实践:
# 安装 Verilator
sudo apt install verilator
# 安装 Icarus Verilog(可选)
sudo apt install iverilog
# 安装 GTKWave(波形查看器)
sudo apt install gtkwave
# 验证安装
verilator --lint-only --version
iverilog -V
密码学硬件实现的关键性能指标:
这些指标之间通常存在 trade-off,设计时需根据应用场景权衡。
本课涉及的核心概念和技术关系:
Verilog 仿真调试的常用方法:
// 调试示例
initial begin
$dumpfile("sim.vcd");
$dumpvars(0, uut);
end
// 断言验证
assert property (@(posedge clk) valid |-> data !== 'x)
else $error("Invalid data when valid!");
# 1. 语法检查
verilator --lint-only module.v
# 2. 创建 C++ 测试主函数
cat > sim_main.cpp << 'EOF'
#include "Vmodule.h"
#include "verilated.h"
int main(int argc, char** argv) {
Verilated::commandArgs(argc, argv);
Vmodule* top = new Vmodule;
top->clk = 0; top->rst_n = 0;
top->eval();
top->rst_n = 1;
for (int i = 0; i < 100; i++) {
top->clk = !top->clk;
top->eval();
}
delete top;
return 0;
}
EOF
# 3. 编译
verilator -cc module.v --exe sim_main.cpp
make -C obj_dir -f Vmodule.mk
# 4. 运行
./obj_dir/Vmodule
密码硬件的性能评估维度:
| 指标 | 单位 | 说明 |
|---|---|---|
| 面积 | GE / LUT | 等效门数或查找表数量 |
| 频率 | MHz | 最大时钟频率 |
| 吞吐量 | Gbps | 每秒处理的数据量 |
| 延迟 | 周期数 | 从输入到输出的周期 |
| 能效 | pJ/bit | 每比特能耗 |
| 面积效率 | Gbps/GE | 单位面积吞吐量 |
不同应用场景对指标优先级不同:IoT 偏重面积和能效,服务器偏重吞吐量。
本课涉及的核心概念和技术关系:
Verilog 仿真调试的常用方法:
// 调试示例
initial begin
$dumpfile("sim.vcd");
$dumpvars(0, uut);
end
// 断言验证
assert property (@(posedge clk) valid |-> data !== 'x)
else $error("Invalid data when valid!");
# 1. 语法检查
verilator --lint-only module.v
# 2. 创建 C++ 测试主函数
cat > sim_main.cpp << 'EOF'
#include "Vmodule.h"
#include "verilated.h"
int main(int argc, char** argv) {
Verilated::commandArgs(argc, argv);
Vmodule* top = new Vmodule;
top->clk = 0; top->rst_n = 0;
top->eval();
top->rst_n = 1;
for (int i = 0; i < 100; i++) {
top->clk = !top->clk;
top->eval();
}
delete top;
return 0;
}
EOF
# 3. 编译
verilator -cc module.v --exe sim_main.cpp
make -C obj_dir -f Vmodule.mk
# 4. 运行
./obj_dir/Vmodule
密码硬件的性能评估维度:
| 指标 | 单位 | 说明 |
|---|---|---|
| 面积 | GE / LUT | 等效门数或查找表数量 |
| 频率 | MHz | 最大时钟频率 |
| 吞吐量 | Gbps | 每秒处理的数据量 |
| 延迟 | 周期数 | 从输入到输出的周期 |
| 能效 | pJ/bit | 每比特能耗 |
| 面积效率 | Gbps/GE | 单位面积吞吐量 |
不同应用场景对指标优先级不同:IoT 偏重面积和能效,服务器偏重吞吐量。