---------------------------------------202/12/19 更新---------------------------------------
在输入时除了密钥的遍历范围因为DES的S盒的“6进4出“机制导致范围限定在0-63以外,明文在作为S盒输入的时候也是被限制在每组长度为64。我将明文数组长度从1000更新为64后的猜测正确率也是100%。
-------------------------------------------起始内容-------------------------------------------
实验目的
- 掌握S盒侧信道攻击的基本原理;
- 掌握汉明重量攻击模型;
- 掌握DPA攻击基本原理和方法。
实验人数
每组1人
系统环境
Windows
实验原理
- 测量阶段,选取随机数量明文和设定好的正确密钥进行异或,得到的6bit结果作为S盒的输入,S盒的输出需统计二进制中1的个数,作为汉明重量,所有输出得到一个汉明重量数组。
- 攻击阶段,需要遍历密钥的所有可能,每次遍历都需经历测量阶段,最后得到所有猜测密钥的汉明重量数组,且每个都需要计算数组元素中间值,作为划分正确密钥得到的汉明重量数组的依据,正确密钥得到的汉明重量数组划分成两个集合,分别计算 x H ‾ = 1 ∣ H ∣ ∑ i ∈ H x i \overline{x_H}=\frac{1}{\lvert H \rvert}\sum_{i\in H}^{}{x_i} xH=∣H∣1∑i∈Hxi, x L ‾ = 1 ∣ L ∣ ∑ i ∈ L x i \overline{x_L}=\frac{1}{\lvert L \rvert}\sum_{i\in L}^{}{x_i} xL=∣L∣1∑i∈Lxi,其中 ∣ ∣ || ∣∣表示集合元素大小,得到差值求均值差 D p a V a l u e = x H ‾ − x L ‾ DpaValue=\overline{x_H}-\overline{x_L} DpaValue=xH−xL,最后选择所有差值最大的所对应的猜测密钥为正确密钥。
实验内容
-
完成Sboxdpa仿真-student.py程序中的空缺部分
-
补充n、plaintext、keyTrue
-
补充HWfun函数,返回输入的汉明重量
-
补充主函数,得到输出相应的汉明重量向量
-
-
完成Sboxdpa-student.py文件中的空缺部分,即
-
补充plaintext、power_std
-
补充DPAfun函数,计算汉明差值
-
补充主函数,求正确猜测密钥
-
-
实验测试2组数据
实验步骤
完善Sboxdpa仿真-student.py程序
补充变量
补充n、plaintext、keyTrue三个变量
n = 9 #数组长度
plainlist = [41, 35, 62, 4, 33, 44, 22, 46, 18] #明文数组
keyTrue = 43 #加密所用密钥
完善HWfun函数
本质上是计算十进制数转换成二进制后含1的数量,则可以采用快速法计算。这种方法运算次数与输入n的大小无关,只与n中1的个数有关。如果n的二进制表示中有k个1,那么这个方法只需要循环k次即可。其原理是不断清除n的二进制表示中最右边的1,同时累加计数器,直至n为0。
补充代码如下:
def HWfun(num):
# 统计输入num的汉明重量并返回
ans = 0
if num == 0:
return 0
while num > 0:
num &= (num - 1)
ans += 1
return ans
为什么n &= (n – 1)能清除最右边的1呢?因为从二进制的角度讲,n相当于在n - 1的最低位加上1。举个例子,8(1000)= 7(0111)+ 1(0001),所以8 & 7 = (1000)&(0111)= 0(0000),清除了8最右边的1(其实就是最高位的1,因为8的二进制中只有一个1)。再比如7(0111)= 6(0110)+ 1(0001),所以7 & 6 = (0111)&(0110)= 6(0110),清除了7的二进制表示中最右边的1(也就是最低位的1)。
完善主函数
使用表格美化库完善输出。
补充代码如下:
if __name__ == "__main__":
# 补充:S盒输出对应汉明重量列表
table = pt.PrettyTable()
hw_std = []
HWout = sboxout(n, plainlist, keyTrue)
for i in range(n):
hw_std.append(HWfun(HWout[i]))
table.add_column('序号',[i for i in range(1,n+1)])
table.add_column('明文-十进制',[index for index in plainlist])
table.add_column('S盒输出-十进制', [index for index in HWout])
table.add_column('S盒输出-汉明重量', [index for index in hw_std])
print(table)
程序运行结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

完善Sboxdpa-student.py程序
补充变量
我在此程序中采用的plaintlist数组(明文数组)是由plainlist = list(np.random.randint(64, size=1000))函数生成的1000长度的数组,模拟教材上的运行基数。同理,power_std数组(正确密钥处理得到的汉明重量数组)同样长度1000,数组内的元素展示位置在8.4数据统计中,“明文数组长度为1000”那里。
完善DPAfun函数
Meanfun函数我有所改动:
def Meanfun(num):
total = 0
length = len(num)
if length == 0:
return 0
for i in range(length):
total = total + num[i]
return total / length
函数思想是取使用猜测密钥处理的汉明重量数组的中间值作为划分使用正确密钥处理的汉明重量数组的依据,随后,函数返回划分后集合的差值。
补充代码如下:
def DPAfun(n, pstd, ptest):
# 以2为界,计算不同汉明重量的集合差值
L_list = []
H_list = []
med = median(ptest)
for i in range(n):
if ptest[i] <= med:
L_list.append(pstd[i])
else:
H_list.append(pstd[i])
return Meanfun(H_list) - Meanfun(L_list)
完善主函数
运行逻辑&思路为遍历所有密钥——64个,将明文和每个密钥异或后的结果作为S盒的输入,得到S盒的输出(模拟DES处理流程),并求得64个汉明重量数组,将64个汉明重量数组带入DPAfun函数进行运算,取DPAfun函数返回值中的最大值对应的密钥,即为正确密钥。
因为DES的

本文介绍S盒侧信道攻击的基本原理与方法,重点讲解汉明重量攻击模型及DPA攻击的应用,通过实例演示如何利用汉明重量差异确定正确密钥。
最低0.47元/天 解锁文章
135

被折叠的 条评论
为什么被折叠?



