本篇文章由ChaMd5安全团队IOT小组投稿
这是近期侧信道攻击与故障注入理论知识的学习总结,写的不好或者不对的地方望大佬斧正
先介绍一下几种常见的加密算法
加密算法
RSA加密算法
RSA是一种非对称加密算法
公钥与私钥的产生
随机选择两个不同大质数 p 和 q,计算 N=p * q
根据欧拉函数,求得 φ(N)=φ(p) * φ(q)=(p−1) * (q−1)
选择一个小于 φ(N) 的整数 e,使 e 和 φ(N) 互质。并求得 e 关于 φ(N) 的模反元素,命名为 d,有
φ(N) mod (e * d) = 1(表示 φ(N) % (e * d) == 1)
此时,(N,e) 是公钥,(N,d) 是私钥。
消息加密
首先需要将消息 以一个双方约定好的格式转化为一个小于 N,且与 N 互质的整数 m。如果消息太长,可以将消息分为几段,这也就是我们所说的块加密,后对于每一部分利用如下公式加密:
c ≡ m^e mod N (^表示平方;明文为m,经过加密后产生密文c)
消息解密
利用密钥 d 进行解密。
m ≡ c^d mod N
如果获取密钥d即可对密文进行解密
AES加密算法
AES是一种分组加密算法,通过迭代的加密操作对数据进行加密
AES128、AES192、AES256分别表示密钥长度128、192、256的加密,其迭代轮数分别为10、12、14
AES在分组的时候将每一个明文块长度分为128bit,也就是16字节,不满足16字节则需要进行填充
(如图,按照顺序可以写成行列式形式)
填充策略:
NoPadding(要求明文必须是16字节的整数倍)
PKCS5Padding(默认)
明文块少于16个字节,在明文块末尾补足相应数量的字符,且每个字节的值等于缺少的字符数
如明文:
{1,2,3,4,5,a,b,c,d,e}
缺少6个字节,则补全为
{1,2,3,4,5,a,b,c,d,e,6,6,6,6,6,6}
ISO10126Padding
明文块少于16个字节,在明文块末尾补足相应数量的字节,最后一个字符值等于缺少的字符数,其他字符填充随机数
如明文:
{1,2,3,4,5,a,b,c,d,e}
缺少6个字节,则可能补全为
{1,2,3,4,5,a,b,c,d,e,5,c,3,G,$,6}
AES128加密的大致流程
首先可以知道一开始密钥为128位,也就是16字节,经过扩展密钥得到最后的176字节
按照普通轮的顺序
字节代替
把明文块的每一个字节都按照S盒替代成另外一个字节
S盒:
0
1
2
3
4
5
6
7
8
9
a
b
c
d
e
f
0
0x63
0x7c
0x77
0x7b
0xf2
0x6b
0x6f
0xc5
0x30
0x01
0x67
0x2b
0xfe
0xd7
0xab
0x76
1
0xca
0x82
0xc9
0x7d
0xfa
0x59
0x47
0xf0
0xad
0xd4
0xa2
0xaf
0x9c
0xa4
0x72
0xc0
2
0xb7
0xfd
0x93
0x26
0x36
0x3f
0xf7
0xcc
0x34
0xa5
0xe5
0xf1
0x71
0xd8
0x31
0x15
3
0x04
0xc7
0x23
0xc3
0x18
0x96
0x05
0x9a
0x07
0x12
0x80
0xe2
0xeb
0x27
0xb2
0x75
4
0x09
0x83
0x2c
0x1a
0x1b
0x6e
0x5a
0xa0
0x52
0x3b
0xd6
0xb3
0x29
0xe3
0x2f
0x84
5
0x53
0xd1
0x00
0xed
0x20
0xfc
0xb1
0x5b
0x6a
0xcb
0xbe
0x39
0x4a
0x4c
0x58
0xcf
6
0xd0
0xef
0xaa
0xfb
0x43
0x4d
0x33
0x85
0x45
0xf9
0x02
0x7f
0x50
0x3c
0x9f
0xa8
7
0x51
0xa3
0x40
0x8f
0x92
0x9d
0x38
0xf5
0xbc
0xb6
0xda
0x21
0x10
0xff
0xf3
0xd2
8
0xcd
0x0c
0x13
0xec
0x5f
0x97
0x44
0x17
0xc4
0xa7
0x7e
0x3d
0x64
0x5d
0x19
0x73
9
0x60
0x81
0x4f
0xdc
0x22
0x2a
0x90
0x88
0x46
0xee
0xb8
0x14
0xde
0x5e
0x0b
0xdb
a
0xe0
0x32
0x3a
0x0a
0x49
0x06
0x24
0x5c
0xc2
0xd3
0xac
0x62
0x91
0x95
0xe4
0x79
b
0xe7
0xc8
0x37
0x6d
0x8d
0xd5
0x4e
0xa9
0x6c
0x56
0xf4
0xea
0x65
0x7a
0xae
0x08
c
0xba
0x78
0x25
0x2e
0x1c
0xa6
0xb4
0xc6
0xe8
0xdd
0x74
0x1f
0x4b
0xbd
0x8b
0x8a
d
0x70
0x3e
0xb5
0x66
0x48
0x03
0xf6
0x0e
0x61
0x35
0x57
0xb9
0x86
0xc1
0x1d
0x9e
e
0xe1
0xf8
0x98
0x11
0x69
0xd9
0x8e
0x94
0x9b
0x1e
0x87
0xe9
0xce
0x55
0x28
0xdf
f
0x8c
0xa1
0x89
0x0d
0xbf
0xe6
0x42
0x68
0x41
0x99
0x2d
0x0f
0xb0
0x54
0xbb
0x16
比如字节
a[0,0]='a'
即
0x61
,按照S盒替换为
b[0x6,0x1]=0xef
,也就是经过替换后
a[0,0]=0xef
行位移
第一行不变
第二行循环左移1个字节
第三行循环左移2个字节
第四行循环左移3个字节
列混淆
经过行位移后的矩阵每一列要和一个名为修补矩阵(fixed matrix)的二维常量数组做矩阵“相乘”,得到对应的输出列
加轮密钥
让输入数组的每一个字节与密钥数组相同位置的字节异或
并且进行密钥扩展(其扩展的算法是可逆的,即根据后16字节密钥可以推算出第一轮对应16字节的密钥)
也就是说,整个AES128加密流程就是在第一轮明文与密钥异或一遍之后,经过9轮普通轮的四种变换,在最后一轮第10轮再进行一次除了列混淆以外的三种变换,完成加密
如果获得任意一轮密钥,结合S逆盒等已知信息可以获得所有密钥并对密文进行解密
示波器基础
数字示波器
采集电压信号
采样:设置采样率(每秒采集信号的数量),一般为芯片信号频率的5-10倍
量化:设置垂直分辨率、垂直范围
搭建采集环境
无源高阻探头要求一端接地
有源差分探头无要求即可测量
加一个电阻,使用有源差分探头采集电阻两端的电压,通过计算出流过电路板的电流来测量电路板的功率
在接地端加一个电阻,用无源高阻探头采集电阻两端的电压,通过计算出流过电路板的电流来测量电路板的功率
但是可能会造成电阻两端接地
使用电流探头,通过测量出流过电路板的电流来测量电路板的功率
使用电磁探头,通过测量芯片表面的电磁辐射来测量电路板的功率
侧信道攻击
其原理是电路能量消耗与参与运算的数据、进行的操作有关
在预测密钥的作用下,通过电路模型我们能够得到所有中间运算结果。再根据能量消耗对中间结果的依赖关系,可以得到预测的能量小孩信息输出
软件功耗模型
汉明重量模型
汉明重量:一串符号中非零符号的个数
由于CPU处理寄存器、总线中数据后预充电将所有的比特值设为1,01转换有能量变化可能泄露数据,所以电路功耗与写入寄存器的数据的汉明重量近似呈线性相关
**T(功耗) = k(常数) * HW(x)(汉明重量) + d(常数) **
汉明距离模型
汉明距离:两个相同长度的二进制数中,对应位不同的数量,也就是两个二进制数异或后1的数量(汉明重量)
某时刻在电路中有器件发生翻转,即由高电平变为低电平或者反之,就会产生动态功耗;否则只产生静态功耗
翻转的bit越多,电路的功耗越大
器件翻转前后功耗大小与翻转前后的二进制数的汉明距离近似呈线性相关
T(功耗) = k(常数) * HD(V0, V1)(汉明距离) + d(常数)
简单功率分析——SPA(Simple channel analysis)
SPA攻击RSA密钥
RSA 可被 SPA 攻击的理论基础来自于 RSA 中包含的快速幂取余算法
快速幂算法如下
C 代码实现为
int PowerMod (int a, int b, int c) { int ans = 1 ; a = a % c; while (b>0 ) { if (b % 2 == 1 ) // 当b为奇数时会多执行下面的指令 ans = (ans * a) % c; b = b/2 ; a = (a * a) % c; } return ans; }
快速幂的计算过程中会逐位判断指数的取值,并会采取不同的操作
所以在程序进行解密的时候,可从能量迹中还原出密钥 d(上图以及代码中的b) 的取值,直接得到的值是 d 的二进制取值的
逆序
SPA攻击AES算法结构
由于不同操作,能量迹波形特征不同,可以通过分析能量迹来确定AES加密时使用的算法结构
差分功率攻击——DPA(Differential Power Analysis)
将大量明文pi与密钥进行加密运算,获得多条能量迹Ti,再将这些明文与猜测的密钥k(256次),进行运算得到多个中间值x,再将x某个状态字节的值作为区分函数将数据分为两组,求出两组的功耗均值, 再将 2 个功耗均值求差,并对其进行统计分析以得出密钥(逐比特)
看例子理解
以AES128为例
可以将其视为除了最后一轮外每轮变换步骤为
的加密方法
攻击步骤:
逐字节对密钥k进行爆破,每个字节需要爆破256次
(0~0xff)
,对于每个猜测的k的值都进行一遍以下操作来逐字节爆破密钥
进行i次 将明文pi与猜测的k进行异或后根据S盒替换得到中间值xi 的操作(也就是说对于密钥k的每个字节,都有i*256个x)
从异或后的中间结果xi中某个状态字节的值作为区分函数(比如判断最后一个字节是否为1)将i个数据对应的i条能量迹(此处的能量迹是使用正确密钥对pi进行加密时采集的能量迹Ti)分为两组,求出两组的功耗均值, 再将 2 个功耗均值求差
只有正确的密钥可以将 2 组具有差异的功耗数据区分开,因此正确密钥的差分功耗值是最大的
(图形大概如图)
这么做的目的是:
对比汉明重量的功耗模型,计算出得xi时,xi中的每个比特,为1的能耗与为0的能耗不同
假设对于某一个猜测的k,计算得出xi时,xi中某个比特为1时功耗为P+a,为0时功耗为P
则只有在这i组能量迹按 使用猜测密钥k加密产生的xi这一比特是否为1分出来的组 与 使用正确密钥加密产生的值的这一比特是否为1分出来的组 一致的情况下,求出两组的功耗均值, 再将 2 个功耗均值求差,其差分功耗a才会比较突出的显示在差分曲线图中的某个点
否则相互抵消的情况下不能将该点的差分功耗明显地区分出来
能量相关分析——CPA(Correlation Power Analysis)
通过 用多个明文与猜测的密钥值所计算出的中间值的汉明重量 与 正常解密流程的能量迹各点 进行线性相关对比,如果存在线性相关性极大的点则说明该计算中间值的过程(使用这个密钥的过程)存在于加密流程中,即可判断密钥正确(逐字节)
看例子理解
以AES128为例
可以将其视为除了最后一轮外每轮变换步骤为
的加密方法
运算的主要功耗在于字节代替阶段,对于1、2变换,可以概括为将输入数据与密钥逐字节异或后根据S盒进行替换
攻击步骤:
对pi进行加密操作,通过示波器获取i条能量迹Ti
对逐字节的密钥k进行爆破,每个字节需要爆破256次
(0~0xff)
,对于每个猜测的k的值都进行一遍以下操作来逐字节爆破密钥
进行i次 将明文pi与猜测的k进行异或后根据S盒替换得到xi 的操作
计算出xi的汉明重量hwi,与对应能量迹Ti中每个点进行相关性分析,生成相关性曲线图
如果某个由猜测的k产生的x的汉明重量与能量迹T中一个点相关系数很大(在-1~1之间),也就是说在每次明文pi与该猜测的密钥k运算结果xi的汉明重量都与明文pi与正确密钥加密时能量迹曲线某点一致,则表示计算产生x(使用这个密钥的过程)在整个加密过程中出现过(相关系数极大的时间点),即可判断该k是正确的密钥
侧信道防御技术
时间维度:随机伪操作/乱序操作——随机化密码设备的能量消耗
振幅纬度:增加噪声/降低功耗——降低能量消耗信噪比,使不同操作数/操作具有一样的能量消耗
故障注入
通过外界干扰改变设备正常逻辑,让程序进行能被利用的出错,并进行利用
if (pay_pwd_is_correct) transfer_money();else reject_operation();
原理及种类
关键路径:组合逻辑电路从输入到输出所经历的正常时延
电压故障注入:电压降低,关键路径变长,大于时钟间隔
时钟毛刺注入:时钟上升沿提前到来,时钟间隔小于关键路径
电磁脉冲注入:电磁效应形成局部感应电流(具体模型学术界仍在讨论)
激光注入:光电效应引起载流子能级跃迁,PN节异常导通
目的
故障注入参数
调试参数过程
错误模型
攻击步骤