研0day4------侧信道一篇
标题就一点都没看懂,我感觉要先学习一下前置知识
AES
16字节
SBox
轮函数
密钥扩展
AES加密算法原理的详细介绍与实现-CSDN博客
侧信道攻击
密码学侧信道攻击(Side-channel Attack):从物理泄露中窃取密钥_侧信道攻击原理和方式-CSDN博客
侧信道(Side-channel)指的是密码设备在执行加密/解密操作时,通过非预期途径泄露的与密钥或明文相关的信息。这些信息通常是设备物理特性的副产品,例如:
运算时的功耗变化(不同指令、不同数据会导致芯片电流波动)
运算时间差异(复杂操作比简单操作耗时更长)
电磁辐射(芯片内部电路开关会产生电磁波)
热量释放(高负载运算区域温度更高)
声音(老式机械设备的运行噪音)
不同数据
↓
不同功耗
↓
不同波形
↓
攻击者记录下来。
这就是:
Power Trace(功耗曲线)
Trace
实际上就是:
一次AES运行时记录的功耗(或电磁)曲线。
密码学侧信道攻击(Side-channel Attack):从物理泄露中窃取密钥_侧信道攻击原理和方式-CSDN博客
几种攻击方式
密码学中的DPA——Differential power analysis差分功耗分析-CSDN博客
① SPA(Simple Power Analysis)简单能量分析
最简单。
直接看功耗。
攻击者直接分析密码运算过程中采集到的能量消耗。通过测定的能量轨迹直接推断出密码设备所执行的操作或所操作的数据。简单能量分析SPA方法使用了能量迹与设备所执行指令之间的依赖关系。
例如:
高 低 高 高 低肉眼分析。
适合简单设备。
缺点是需要泄露比较明显,对噪音的敏感性大。
② DPA(Differential Power Analysis)差分能量分析
DPA——差分能量分析(Differential Power Analysis)-CSDN博客
相比于SPA为更高级的功耗分析手段,允许攻击者通过对多次密码学操作所收集到数据进行统计分析计算出在密码学运算中的中间值。
通过大量的能量轨迹计算能量轨迹和数据的依赖性。
最经典。
大量Trace。
统计分析。
恢复Key。
优点是,即使泄露较小,也可以有效识别,有天然的对噪音的过滤,
缺点是需要的能量轨迹很多。
③ CPA(Correlation Power Analysis)相关功耗分析
现在最常见。
利用:
Pearson相关系数。(DPA不会计算相关系数,看的是两组平均功耗的差值)
论文里面PCC就是这个。
④ Template Attack(模板攻击)
模板攻击 - 火腿烧豆腐 - 博客园
论文第二章介绍了。
它属于:
Profiled Attack。
是指攻击者会在目标设备的同类型设备或者其复制品上创建一个"profile",随后利用这一"profile"快速恢复目标设备的密钥。
步骤:
第一步:
拿到一台一样的设备。
知道Key。
训练模板。
第二步:
攻击目标设备。
匹配模板。
恢复Key。
⑤ Deep Learning SCA
近年来最热门。
不用人工设计统计模型。
直接:
Trace ↓ CNN ↓ Key论文里面:
CNN就是这个。
用深度学习模型自动学习功耗泄露特征,从而恢复密码密钥的攻击方法。
1. 为什么需要 Deep Learning SCA?
先回顾传统 CPA。
CPA 的思路:
明文 | 猜测密钥 | AES中间值 | 功耗模型(HW) | 相关分析 | 恢复密钥例如:
HW(SBOX(plaintext ^ key_guess))这里有一个问题:
CPA需要人工选择泄露模型
比如:
假设芯片泄露
功耗 ≈ 汉明重量(HW)那么CPA有效。但是实际硬件:
可能泄露:
- 汉明重量
- 汉明距离
- 电容效应
- 寄存器翻转
- 多个中间状态组合
- 噪声影响
真实泄露模型:可能是:
功耗=f(多个未知因素)人工很难建立准确模型。
于是出现:
能不能让机器自己学习功耗和密钥之间的关系?
答案就是Deep Learning SCA。
2. Deep Learning SCA核心思想
传统CPA:
人为设计:
明文+密钥 | | ↓ HW模型 | ↓ 预测功耗深度学习:
让神经网络学习:
功耗轨迹 | | ↓ 神经网络 | | ↓ 密钥信息也就是说:
不需要知道:
真实泄露模型神经网络自己寻找:
哪些采样点重要 哪些波形特征对应密钥3. Deep Learning SCA攻击流程
整体流程:
ASCAD数据集 | | ↓ 功耗轨迹 Trace | | ↓ 预处理 | | ↓ CNN / MLP / RNN模型 | | ↓ 训练 | | ↓ 预测密钥4. 数据组成
和CPA一样,需要:
(1) 功耗轨迹
例如:
Trace1: 0.12 0.15 0.20 ... 0.33 Trace2: 0.11 0.17 0.22 ...表示:
芯片执行AES时的功耗变化。
(2) 明文
例如:
plaintext: 32 88 31 e0 ...(3) 密钥
训练阶段知道:
key byte=0x2b测试攻击阶段不知道。
5. 深度学习模型学习什么?
以AES第0字节为例。
AES计算:
plaintext[0] XOR key[0] ↓ SBOX ↓ 中间状态 ↓ 功耗泄露功耗中包含:
隐藏信息 | | ↓ key神经网络学习:
功耗波形 ↓ 内部AES状态 ↓ 密钥概率6. 常用深度学习模型
① MLP(多层感知机)
小白笔记:对MLP多层感知机概念、结构、超参数的理解-CSDN博客
www.cnblogs.com/guxuanqing/p/19171270
最简单。
结构:
Trace | Dense层 | Dense层 | Softmax | 256分类结果输出:
key=0x00 概率0.01 key=0x01 概率0.02 ... key=0x2b 概率0.92适合:
- 简单数据
- 小规模实验
(1)感知机(PLA,Perceptron Learning Algorithm):只有输入和输出层,这两层共同组成了一个简单的神经元,即单个神经元模型,是较大神经网络的前身。它是一个线性的二分类器,但它对非线性的数据并不能进行有效的分类。因此我们可以加深这个神经元的网络层次,理论上来说,多层网络可以模拟任何复杂的函数。以下是感知机的概念公式:
(2)多层感知机(MLP,Multi-Layer Perceptron):由感知机推广而来,它最主要的特点就是有多个神经元层,因此 MLP 也被称为人工神经网络(Artificial Neural Network,ANN)。MLP 是一种特定类型的人工神经网络,它由多个神经元组成,通常包括一个输入层、一个或多个隐藏层以及一个输出层。相对而言,ANN 是一个更广泛的术语,它包括了所有由神经元组成的网络,而 MLP 则是 ANN 中的一个特例,指代具有多个层的前馈神经网络。所以在讨论上,MLP 和 ANN 可以互换使用。
多层感知机的结构神经网络的预测能力来自网络的分层或多层结构,所以神经网络的层次结构很重要。
多层感知机的层次
多层感知机是指具有至少三层节点:(1)输入层(接收数据),(2)一些中间层(一个或多个隐藏层,计算数据),(3)输出层(输出结果)的神经网络。
(MLP并没有限定隐层的数量,对于输出层神经元的个数也没有限制,所以我们可以根据各自的需求选择合适的隐层层数。)那么感知机与多层感知机的结构是什么样的呢?(左图为感知机,右图为多层感知机)
从结构图中我们可以看出,多层感知机这三类给定层(输入、中间、输出层)中的每个节点都会连接到相邻层中的每个节点(全连接),所以这里有一个MLP中最重要的一个组成就是Dense Layer(全连接层/线性层/稠密层,在本文中我称之为全连接层),它在MLP中发挥的是什么样的作用呢?
1.Dense Layer(全连接层)
全连接层中有一个可以学习的参数 w(mxn,n:输入特征的维度,m:输出的向量的长度),还有一个参数 b(偏置,长为m),所以在这一层我们会对输入的数据 x 进行下面的公式计算,得到输出 y。(y也是一个长为m的向量)
那么之前我们所了解到的线性回归,本质上就可以认为是一个全连接层,但是只有一个输出,即m=1,在神经网络中,我们通常将线性结构表示为下图:(事实上,我认为这就是一个单层的感知机PLA,注意将这幅图与下面的MLP进行对比,你可以发现到底哪些是隐藏层)
2.如何由线性结构变为多为多层感知机
我们了解了线性回归,知道了多层感知机有三个层次,那么如何将线性结构变为多层的感知机呢?——重点就是:全连接(Dense) + 激活函数(引入非线性)。
因为想做到非线性,那我们可以尝试使用多个全连接层,但是将全连接层简单的叠加在一起还是线性的,所以要加入非线性的东西在里面,也就是激活函数(比如sigmoid、Relu等),才能实现我们想要的非线性(去拟合各种各样的函数,更具现实意义)。以下是具有一层隐藏层的MLP(左)和具有三层隐藏层的MLP(右)结构示图:
② CNN(卷积神经网络)
【深度学习】一文搞懂卷积神经网络(CNN)的原理(超详细)_卷积神经网络原理-CSDN博客
卷积神经网络(CNN)全面解析 - 实践 - ljbguanli - 博客园
目前SCA最常用。
原因:
功耗曲线类似:
时间序列CNN擅长发现局部特征。
例如:
功耗:
------------------------------------------------ ↑ | AES SBOX泄露位置CNN自动找到:
第3000采样点附近存在密钥相关信息。
结构:
Trace ↓ Conv1D ↓ Pooling ↓ Dense ↓ Softmax ↓ 256类别ASCAD论文大量使用CNN。
③ RNN / LSTM
处理时间序列。
例如:
功耗变化:
t1 | t2 | t3 | t4LSTM可以学习:
前后采样点关系。
7. 分类方式
Deep Learning SCA通常转换成:
密钥分类问题
例如攻击:AES第0字节。
类别:
0x00 0x01 0x02 ... 0xff共:
256类所以最后一层:
Softmax:
输出:
[ 0.001, 0.002, ... 0.95, ... ]概率最高:
就是猜测密钥。
8. 举个例子
训练数据:
10000条trace。
其中:
Trace1: plaintext=0x32 key=0x2b power=[0.1,0.3,0.8...]告诉神经网络:
这条功耗对应密钥0x2b训练很多次:
网络发现:
某些波形特征 ↓ 对应0x2b攻击阶段:
输入新的trace:
power=[0.12,0.31,0.82...]网络输出:
0x2b概率: 0.96恢复密钥。
9. Deep Learning SCA 和 CPA区别
| CPA | Deep Learning SCA | |
|---|---|---|
| 方法 | 统计分析 | 机器学习 |
| 泄露模型 | 人工设计HW | 自动学习 |
| 需要知道AES结构 | 需要 | 较少 |
| 抗噪声 | 一般 | 较强 |
| 选择POI | 人工 | 自动 |
| 数据需求 | 较少 | 较多 |
| 计算量 | 低 | 高 |
AES 第一字节的功耗侧信道攻击实操 -----CPA
还没学完 但我想做cpa实操!!
我靠居然把我做亢奋了!!!!
终于!!!!没在看那些破理论了!!!!!
在官网下载了ASCAD.ZIP
Jeu de données - ASCAD | data.gouv.fr
ASCAD.h5就是实验数据
.h5文件不是普通文件,它类似一个“小型数据库”,里面有层级结构
1.查看ASCAD结构
import h5py file="ASCAD.h5" with h5py.File(file,'r') as f: print(list(f.keys())) print( f["Profiling_traces"].keys() ) print( f["Attack_traces"].keys() )Profiling_traces
翻译:
建模轨迹 / 训练轨迹
用于:
- 训练神经网络
- 建立泄露模型
比如:
Profiling_traces | | 50000条功耗波形 | | 告诉模型: 这个波形对应哪个中间值类似机器学习里的:
训练集里面有:
Profiling_traces ├── traces └── metadataAttack_traces
翻译:
攻击轨迹
用于:
真正恢复密钥。
类似机器学习里的:
测试集在CPA里面,我们主要使用:
Attack_traces因为我们想:
根据真实功耗猜AES密钥。
Attack_traces ├── traces │ └── metadatatraces
功耗轨迹
比如:
traces[0] [ 0.12, 0.15, 0.19, 0.25, ... ]表示:AES运行过程中每一个时间点的功耗。
画出来类似:
功耗 ^ | | /\ /\ | / \_____/ \ | |________________________> 时间metadata
就是这条功耗对应的额外信息
例如:
metadata { plaintext: [32,43,246,...], key: [43,126,21,...], mask: [...] }里面保存:
- 明文 plaintext
- 密钥 key
- 掩码 mask
- 密文 ciphertext
这些信息用于分析。
所以完整结构:
ASCAD.h5 │ ├── Profiling_traces │ | │ ├── traces │ | │ └── metadata │ │ └── Attack_traces | ├── traces | └── metadata2.读取攻击数据
import h5py import numpy as np f=h5py.File( "ASCAD.h5", "r" ) traces=np.array( f["Attack_traces/traces"] ) metadata=np.array( f["Attack_traces/metadata"] ) print(traces.shape) print(metadata.dtype)10000条功耗。
每条:
700个采样点。
3.取明文
10000条明文。
每条16字节。
AES
s盒进行字节代换AES加密算法原理的详细介绍与实现-CSDN博客
密钥是16个字节 选择攻击字节为k0
汉明重量模型
简单来说就是一个数的二进制包含'1'的个数,如0x00的HM为0,0xFF的HM为8,0x1和0x2的HM都为1
功耗 ∝ 数据中1的数量
皮尔逊相关系数
https://zhuanlan.zhihu.com/p/1950132687949000900
皮尔逊相关(Pearson correlation)系数概述及其计算例_皮尔逊相关系数-CSDN博客
又称皮尔逊积矩相关系数,通常用字母r表示,用于衡量两个连续型变量 X 和 Y 之间的线性关系。它由卡尔·皮尔逊在19世纪末提出,基于协方差的概念发展而来 编辑Baidu+1。
- r = 1表示完全正线性相关,即 Y 随 X 增加而严格增加。
- r = -1表示完全负线性相关,即 Y 随 X 增加而严格减少。
- r = 0表示两变量之间没有线性相关关系,但不排除非线性关系存在
计算公式
总体皮尔逊相关系数定义为两个变量协方差与标准差的比值:
ρX,Y=Cov(X,Y)σXσY
其中,Cov(X,Y) 为 X 和 Y 的协方差,σ_X 和 σ_Y 分别为 X 和 Y 的标准差。
对于样本数据,皮尔逊相关系数可表示为:
r=∑i=1n(xi−x¯)(yi−y¯)∑i=1n(xi−x¯)2·∑i=1n(yi−y¯)2
其中,x_i 和 y_i 为样本观测值,x¯ 和 y¯ 为样本均值,n 为样本数量 知乎+1。
理解与应用
皮尔逊相关系数不仅反映相关方向(正相关或负相关),还反映相关程度。其值越接近 ±1,表示线性关系越强;越接近 0,表示线性关系越弱。
import h5py import numpy as np import matplotlib.pyplot as plt # ============================== # 1. 读取 ASCAD 数据 # ============================== filename = "ASCAD.h5" f = h5py.File(filename, "r") # 功耗轨迹 traces = np.array( f["Attack_traces/traces"] ) # 元数据 metadata = f[ "Attack_traces/metadata" ] # 明文 plaintext = metadata["plaintext"] # 真实密钥(仅用于验证) 取第0条数据的key real_key = metadata["key"][0] print("Trace shape:", traces.shape) print("Plaintext shape:", plaintext.shape) print("Real key:", [hex(x) for x in real_key]) # ============================== # 2. AES SBox # ============================== SBOX = [ 0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5, 0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76, 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0, 0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0, 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc, 0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15, 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a, 0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75, 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0, 0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84, 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b, 0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf, 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85, 0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8, 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5, 0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2, 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17, 0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73, 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88, 0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb, 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c, 0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79, 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9, 0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08, 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6, 0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a, 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e, 0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e, 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94, 0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf, 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68, 0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16 ] # ============================== # 3. 汉明重量模型 HW # ============================== def HW(x): return bin(x).count("1") # ============================== # 4. 攻击第0个字节 # ============================== # AES第0字节明文 pt = plaintext[:,0] //取所有明文的第0个字节。 num_traces = len(pt) //轨迹数量 # 保存256个密钥猜测,建立猜测矩阵,因为aes密钥长度是16个字节,一个字节8bit,2^8 = 256 hypothesis = np.zeros( (256,num_traces) ) print("Generating hypothetical power...") for key_guess in range(256): //遍历所有密钥猜测 for i in range(num_traces): //遍历每条轨迹 # 计算AES中间值(AES第一轮 明文 xor key--->subbytes--->中间值) value = SBOX[ pt[i] ^ key_guess ] # HW泄露模型,转换成预测功耗 hypothesis[key_guess,i] = HW(value) print("Hypothesis finished") # ============================== # 5. CPA相关分析 # ============================== correlation=[] //每个key猜测最大的相关系数。 print("Running CPA...") for key_guess in range(256): max_corr=0 //保存当前密钥最大的相关。 for sample in range( traces.shape[1] ): corr = np.corrcoef( hypothesis[key_guess], traces[:,sample] )[0,1] //计算皮尔逊相关 if abs(corr)>max_corr: //保存最大相关,因为正负相关都有可能 max_corr=abs(corr) correlation.append(max_corr) //保存该密钥结果 # 最大相关对应密钥 recovered_key = np.argmax( correlation ) print("===================") print( "Recovered key byte:", hex(recovered_key) ) print("===================") # ============================== # 6. 绘制相关曲线 # ============================== plt.figure(figsize=(10,5)) //创建画布 plt.plot( correlation ) plt.xlabel( "Key Guess" ) //x轴 plt.ylabel( "Correlation" ) //y轴 plt.title( "CPA Result AES byte 0" ) plt.grid() plt.show()总结:CPA把AES一个字节的密钥看成256种可能,每猜一个密钥,就计算这个猜测对应的理论功耗(hypothesis),然后和真实功耗曲线比较,相关性最高的那个猜测就是正确密钥。
没有攻击成功 因为
ASCAD.h5它是带掩码(masking)数据集。
带掩码(Masking)的 AES,就是专门为了让 CPA 这类一阶侧信道攻击失败而设计的。
掩码(mask)(失败的原因)
1. 普通 AES 为什么 CPA 能成功?
假设 AES 第一轮第一字节:
明文 P │ XOR │ 密钥 K │ SBox │ 中间值 V │ CPU计算 │ 功耗CPA 的思想就是:
对于每一个密钥猜测
K = 0 K = 1 ... K = 255计算
V = SBox(P ⊕ K)然后预测它的汉明重量
HW(V)例如
V = 0x53 二进制 01010011 共有4个1 HW=4真实芯片功耗也近似满足
功耗 ≈ HW(V)因此
预测功耗
HW(V)和
真实功耗
Trace高度相关。
于是正确密钥出现最高峰。
2. Masking 做了什么?
带 Mask 后,中间值不会直接参与计算。
而是随机加一个 Mask。
例如:
真正计算的是
V = SBox(P⊕K) Mask = RCPU里面变成
V' = V ⊕ R例如
V 10101100随机Mask
R 11010010真正存进寄存器的是
10101100 ⊕ 11010010 = 01111110下一次运行
Mask 又变了
例如
00110101得到
10011001第三次
Mask
11101000得到
01000100所以
同一个
SBox(P⊕K)每一次都变成完全不同的数据。
3. 为什么 CPA 失败?
CPA 预测的是
HW(SBox(P⊕K))例如
HW(0xAC)=4但是芯片泄漏的是
HW(SBox(P⊕K)⊕Mask)第一次
HW(0x7E)=6第二次
HW(0x99)=4第三次
HW(0x44)=2Mask 每次随机。
于是
预测值
4 4 4 4 4 4真实值
6 2 5 3 4 7 ...完全没有相关性。
于是 CPA 图变成
0.05 0.04 0.06 0.05 0.04 0.05没有尖峰。
这正是你画出来的图。
4. 为什么数据集里面要保存 masks?
你看到
metadata ( 'plaintext', 'ciphertext', 'key', 'masks' )说明实验人员知道每一次用了什么随机 Mask。
例如
Trace1 Mask = 0x53Trace2 Mask = 0xB7Trace3 Mask = 0x11真实芯片当然不会告诉攻击者这些 Mask。
但数据集保存下来,是为了:
- 验证 Mask 是否正确工作;
- 研究新的侧信道攻击方法;
- 测试二阶 CPA、模板攻击等高级方法。
5. 为什么二阶 CPA 能攻击?
Mask 不是凭空消失,它也会在芯片中参与运算。
芯片通常会泄漏两个位置:
泄漏1: Mask以及
泄漏2: SBox(P⊕K)⊕Mask一阶 CPA 只分析一个泄漏点:
Trace[t]二阶 CPA 会把两个泄漏点组合起来,例如:
(L1-μ1) × (L2-μ2)其中:
- L1L1L1:第一个泄漏点(Mask)
- L2L2L2:第二个泄漏点(Masked SBox 输出)
- μ1,μ2\mu_1,\mu_2μ1,μ2:对应泄漏点的平均值
这样可以在统计意义上抵消随机 Mask 的影响,从而重新建立与真实中间值的相关性。
因此,二阶 CPA 会重新出现明显的相关峰,而一阶 CPA 基本看不到峰值。
so 实验失败