【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。同样,攻击者也可以基于其他中间值来实施攻击。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理