【SCA】DPA matlab代码总结(一)

2022.3.11 星期五

一、相关理论基础

本次实验是基于 AES 的 DPA 攻击,使用虚拟操作加密,使用《能量分析攻击》这本书里配套的能量轨迹,这个训练集是使用小电阻耦合得到的;

由www.dpabook.org 提供的代码;

该代码原理讲解位于《能量分析攻击》p6-8;bit泄漏模型;

需要了解AES的加密过程。

《密码旁路分析原理与方法》郭世泽 p96-101 也有相关内容。

常用的相关性分析包括差分分析方法和线性相关系数分析,原理是利用统计方法,提取部分秘密信息,与旁路泄漏轨迹中某个特定位置的相关性。

差分分析方法通过处理0和1对应功耗均值之间的差来测量相关性:

 

 二、差分功耗分析仿真

使用WS1的训练集:该能量迹对应inputs加载,addRoundKey,subbytes操作。

1.dpa函数

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
%%WS1.mat:该能量迹对应inputs加载,addRoundKey,subbytes操作。
%inputs 200x1 200条明文,但只给了16个输入字节的一个字节。
%traces 200x50000
%subytes 1x256 :字节替换,通过一个非线性的替换函数,用查找表的方式把每个字节替换成对应的字节。
%byte_Hamming_weight 字节汉明重量【本程序没有用】
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%dpa函数
function [key_trace] = dpa1(traces,SubBytes,inputs)
%差分攻击
%第一步加载,s盒、能量迹、明文
 %load SubBytes;%加载AES的S盒
 %load races;能量迹
 %load inputs;明文
%第二步 [key_trace] = dpa1(traces,SubBytes,inputs)
%第三步  show_plots(key_trace,1,256,4,5000)最后一个5000为y坐标轴的范围,4为每次出现图像的个数
 
[m,n] = size(traces);
key = [0:255];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%方法一%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%addRoundKey:明文和密钥异或后的数据为mix
for i=1:m
    mix(i,:) = bitxor(inputs(i),key);
end
 
s= reshape(SubBytes, 16, 16)';%将SubBytes1x256转成16x16【注意转置】
after_sbox = zeros(m,256);
%s盒输入,字节替换
         %每个单字节数据的高 4 位作为 x 值,低 4 位作为 y 值。
         %然后根据行列号在 S 盒置换表中查找对应值,将找到的单字节数据作为字节替换操作的输出结果。
         %S 盒可以作为查找表实现。可能只有 256个字节可以替换的值,因此需要 256 个字节的内存。
for i=1:m
     for j=1:256
         h=bitget( mix(i,j),8:-1:5);%s盒输入的高四位二进制【bitget获取指定位置的位】
         l=bitget( mix(i,j),4:-1:1);%s盒输入低四位二进制
         H=bin2dec(num2str(h));%s盒输入的高四位二进制转十进制
         L=bin2dec(num2str(l));%s盒输入低四位二进制转十进制
         after_sbox(i,j)=s(H+1,L+1);%最终得到s和代换后的数据
     end
end  
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%结束%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
%%%%方法二:另一种字节替换方式%%%%%%%%%%%%%%
%after_sbox = zeros(m,256);
%for i=1:m
%    after_sbox(i,:) = SubBytes(bitxor(inputs(i),key)+1);
%end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 
 key_trace = zeros(256,n);%n=5000;
    power_consumption = bitget(after_sbox,1);%攻击位置是s盒变换后的数据的LSB【比特模型】;数据为0和1;
    for i=1:256
        %一次AES加密操作的能量消耗与after_sbox的LSB之间的依赖关系
        %第1bit为1的能量迹放一波,为0的放一波,相减后,最大尖峰的为正确的猜测密钥
        %无尖峰:如果用错误的密钥计算,没有依赖性
     %小尖峰:该密钥计算得出的与实际测量的不完全独立,但依赖性远远小于正确的密钥
        key_trace(i,:) = sum(traces(find(power_consumption(:,i)==1),:)) - sum(traces(find(power_consumption(:,i)==0),:));
    end
   save  key_trace;%key_trace 256x5000
end<br><br>

 

2.show_plots函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
function show_plots(variable, firstplot, lastplot, step, yscale)
 
%SHOW_PLOTS plots rows of a matrix in separate windows
%单独的窗口中绘制矩阵的行
% DESCRIPTION:
%
% show_plots(variable, firstplot, lastplot, step, yscale)
% plots each row a matrix in a separate window
%
% - variable : 应绘制的矩阵         
% - firstplot (optional): 要绘制的第一行的编号;默认值为1
% - lastplot  (optional): 要打印的最后一行的编号;默认值是行的总数
% - step      (optional): 同时显示的绘图数量;默认值为6(大屏幕使用6,小屏幕使用4))
% - yscale    (optional): 设置y轴上显示的值的范围;显示从-yscale到+yscale的值;yscale的默认值为1    
%      
%
% EXAMPLE:
%                                           
% show_plots(unidrnd(10,8,10),1,8,4,10)
 
 
if (~(exist('yscale','var') == 1))
    yscale = 1;
end
 
if (~(exist('firstplot','var') == 1))
    firstplot = 1;
end
 
if (~(exist('lastplot','var') == 1))
    lastplot = size(variable,1);
end
 
if (~(exist('step','var') == 1))
    step = 6;
end
 
for key=firstplot:step:lastplot
 
    for i=key:(key+step - 1)
 
       figure(i - key +1);
 
       if (i<=lastplot)
            keydata = variable(i,:);
          
            n = length(keydata);
 
            plot(keydata);
            axis([0 n -yscale yscale])
            xlabel('time')
            ylabel('Voltage / Corrlelation')
 
            titletext = sprintf('Plot Number: %d, Max: %2.4f, Min: %2.4f',i, max(keydata), min(keydata));
            titletext = strrep(titletext,'\','\\');
            titletext = strrep(titletext,'_','\_');
            title(titletext);
       else
%          close
       end
   end
    
   disp('Press any key for next file')
   pause;
end

 3.函数调用

1
2
3
load('WS1.mat');
[key_trace] = dpa1(traces,SubBytes,inputs);
show_plots(key_trace,1,256,4,5000);

三、仿真结果

由以上程序可以得到下面结果,可以看出,当猜测的密钥错误时,没有明显的尖峰。

其中index_key = 44时,尖峰明显,说明该子密钥是是43的可能性很大

四、总结

 DPA利用了一个这样的事实:微控制器的能量消耗依赖于算法执行过程中所处理的中间值。本次实验的能量消耗依赖于AES加密第一轮中的SubBytes变换的第一个输出字节的MSB。同样,攻击者也可以基于其他中间值来实施攻击。                                                                            

 
posted @   学习记录本  阅读(1066)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示