侧信道攻击之时序攻击(Time attack)
字数 1074 2025-08-07 08:22:00
时序攻击(Time Attack)技术详解
一、侧信道攻击概述
侧信道分析是一种新型的密码破解手段,通过分析加密设备在运行过程中产生的时间消耗、功率消耗或电磁辐射等旁路信息来达到攻击效果。主要类型包括:
- 时序攻击(Time Attack)
- 能耗攻击(Power Analysis)
- 电磁攻击(EM Analysis)
与传统密码分析相比,侧信道攻击的有效性更高,已成为密码分析研究的热点。
二、时序攻击基本原理
时序攻击是一种侧信道攻击,攻击者通过分析加密算法的时间执行差异来推导出密码。其核心原理是:
- 每个逻辑运算在计算机中需要时间执行
- 根据输入不同,执行时间会有微小差异
- 通过精确测量这些时间差异,可以反推出密码
这与SQL注入中的时间盲注类似,都是利用"时间"这种旁路信息来判断程序内部状态。
三、基于strcmp的密码恢复攻击
1. 攻击场景
系统使用strcmp函数比较用户输入密码和系统内置密码,strcmp的C语言实现如下:
int strcmp(const char *s1, const char *s2) {
for(; *s1 == *s2; s1++, s2++)
if(*s1 == '\0')
return 0;
return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1);
}
2. 时间差异分析
- 比较相同字符时:继续比较下一位
- 比较不同字符时:立即返回
- 因此不同输入会导致不同的比较次数,从而产生时间差异
示例:
strcmp("123","000"):第1位不同,执行时间1tstrcmp("123","100"):第2位不同,执行时间2t
3. 攻击实现
为放大时间差异,修改strcmp增加延时:
int new_strcmp(const char *s1, const char *s2) {
for(; *s1 == *s2; s1++, s2++, usleep(5000)) // 相同字符增加5ms延时
if(*s1 == '\0')
return 0;
return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1);
}
4. 逐位破解实现
通过测量时间差异逐位破解密码:
#include <stdio.h>
#include <time.h>
clock_t start, end;
unsigned char password[] = "admin888";
int main() {
int bool_end_flag = 1, leak_str_index = 0;
double strcmp_time = 0.0, diff_time = 0.0;
unsigned char guess_char = 0;
unsigned char leak_str[16] = {0};
while(bool_end_flag) {
bool_end_flag = 0;
for(guess_char = 1; guess_char != 0; guess_char++) {
leak_str[leak_str_index] = guess_char;
start = clock();
new_strcmp(password, leak_str);
end = clock();
diff_time = (double)(end-start)/CLK_TCK - strcmp_time;
if(0.004 < diff_time && diff_time < 0.008) { // 判断5ms延时
printf("Hint byte:'%c', Leak out:%s\n", guess_char, leak_str);
bool_end_flag = 1;
strcmp_time = (double)(end-start)/CLK_TCK;
break;
}
}
leak_str_index++;
}
return 0;
}
四、GF(2^8)有限域乘法的时序攻击
1. 有限域乘法实现
unsigned char xtime(unsigned char x) {
unsigned char y;
y = x << 1;
if(x & 0x80) {
y ^= 0x1B;
}
return y;
}
时间差异:
- 最高位x7=0:处理1次
- 最高位x7=1:处理2次(多一次异或操作)
2. 加密算法示例
unsigned char encode(unsigned char a) {
unsigned char k = 0xAE, x, y; // k为密钥
x = a ^ k;
x = S_Box[(x >> 4) & 0xf][x & 0xf]; // AES S盒替换
y = xtime(x);
return y;
}
3. 攻击步骤
- 准备随机样本并记录加密时间
- 按时间将样本分为两组:
- 短时间组(1t)
- 长时间组(2t)
- 计算两组平均时间差
- 遍历猜测k值(0x00-0xFF),模拟加密过程
- 按原始分组计算时间差,相关性最强的k值即为正确密钥
4. 攻击实现代码
#include <stdio.h>
#include <time.h>
#include <math.h>
unsigned char xtime(unsigned char x) {
unsigned char y;
y = x << 1;
if(x & 0x80) {
y ^= 0x1B;
usleep(10000); // 增加10ms延时
}
return y;
}
int main() {
double delay_group_time_sum = 0.0, nodelay_group_time_sum = 0.0;
int i = 0, guess_k = 0;
int sample_num = 0x10, delay_cnt = 0, nodelay_cnt = 0, bool_delay_group[0xFF] = {0};
unsigned char sample = 0x00;
// 收集样本时间数据并分组
for(sample = 0; sample < sample_num; sample++) {
start = clock();
encode(sample);
end = clock();
run_time = (double)(end-start)/CLK_TCK;
if((int)(run_time/0.01) == 1) {
bool_delay_group[sample] = 1;
delay_cnt++;
} else {
bool_delay_group[sample] = 0;
nodelay_cnt++;
}
}
// 猜测k值
for(guess_k = 0; guess_k <= 0xFF; guess_k++) {
for(sample = 0, delay_group_time_sum = 0.0, nodelay_group_time_sum = 0.0;
sample < sample_num; sample++) {
start = clock();
guess_encode(sample, guess_k);
end = clock();
run_time = (double)(end-start)/CLK_TCK;
if(bool_delay_group[sample])
delay_group_time_sum += run_time;
else
nodelay_group_time_sum += run_time;
}
// 计算相关性
printf("0x%02X, %lf\n", guess_k,
fabs(delay_group_time_sum/delay_cnt - nodelay_group_time_sum/nodelay_cnt));
}
return 0;
}
五、防御措施
- 恒定时间算法:确保所有操作无论输入如何都执行相同时间
- 随机延时:添加随机时间延迟干扰时间测量
- 操作屏蔽:对所有分支路径执行相同操作
- 硬件防护:使用专用加密芯片防止侧信道泄露
六、总结
时序攻击作为一种有效的侧信道攻击手段,对密码系统构成严重威胁。通过本文的两个实例可以看出:
- 即使是简单的字符串比较也可能泄露信息
- 密码学原语的实现细节可能引入可被利用的时间差异
- 防御时序攻击需要从算法设计和实现层面进行考虑
安全开发中应始终遵循"恒定时间"原则,对所有敏感操作进行安全审计,防范此类攻击。