2022.3.11 星期五
一、相关理论基础
本次实验是基于 AES 的 DPA 攻击,使用虚拟操作加密,使用《能量分析攻击》这本书里配套的能量轨迹,这个训练集是使用小电阻耦合得到的;
由www.dpabook.org 提供的代码;
该代码原理讲解位于《能量分析攻击》p6-8;bit泄漏模型;
需要了解AES的加密过程。
《密码旁路分析原理与方法》郭世泽 p96-101 也有相关内容。
常用的相关性分析包括差分分析方法和线性相关系数分析,原理是利用统计方法,提取部分秘密信息,与旁路泄漏轨迹中某个特定位置的相关性。
差分分析方法通过处理0和1对应功耗均值之间的差来测量相关性:
二、差分功耗分析仿真
使用WS1的训练集:该能量迹对应inputs加载,addRoundKey,subbytes操作。
1.dpa函数
%%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
2.show_plots函数
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.函数调用
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。同样,攻击者也可以基于其他中间值来实施攻击。