CPA和DPA
CPA(Connectional Power Analysis):相关性能量攻击,主要通过分析相关性来猜测密钥。
DPA(Differential Power Analysis):差分能量攻击,主要通过计算差值,比骄傲大小来分析猜测密钥的合理性。
完成的内容
攻击对象:
其中sbox是des中的6入4出的s盒子,C和K是6bit数,Sout是4bit的数。
要求:已知C的值和Sout(c,k)对应的信号值,攻击K。
测量仿真阶段:
输入20个随机明文C(C1至C20),固定密钥Ktrue,产生20个仿真信号P。
假设计算阶段
遍历所有可能的k(从000000到111111,共64个),求输入对应中间值Sout的汉明重量HW
数据二:
CPA攻击
数据二中每一列对应某一个猜测密钥K,用数据二的每一列HW分别与数据一中最后一列P计算相关系数ρ,并将其记录至数据三的ρ0至ρ63;再求这64个值中最大值ρi=Max(ρ),则i即为正确密钥Ktrue。
最大相关:R43=0.835214
正确密钥:101011
DPA攻击
1、在数据二中,首先观察第一列k=0对应的hw重量,将其对应能量值p根据hw的大小(以2为分界)分成两大类,下面给一个例子:比如在k=0时,计算出20个对应的汉明重量,将对应信号p与其同列,再根据汉明重量大小分类,然后将同一类中的所有信号值做平均,分别求出p0和p1,再求差分Δ(k=0)=|p1-p0|。
2、针对k=1/2/…/63,重复1、的过程,分别求出Δ(k=1)、Δ(k=2)…、Δ(k=63)。
3、比较这64个差分值的大小,求出最大值Δ(k=j)=max(Δ),此时对应j即为真实密钥Ttrue。
最大差分值:Deta43=9.04762
正确密钥:101011
源代码
#include <iostream>
#include<math.h>
#include<iomanip>
using namespace std;
int HWFun(int num);
int Sboxout(int num, int Nkey,int i);
double Corr(int n, int Pstd[], int Ptest[]);
double meanNum(int n, int num[]);
void Dpa();
int S_Box1[4][16] = { //8个S盒 三维数组
// S1
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 };
int mingwen[20] = { 41,35,62,4,33,
44,22,46,18,16,
9,49,49,59,41,
43,51,38,27,60 };
int HWw[64][20];
int Ptest[64][20];
int Pstd[20];
int HWstd[20];
//DPA
double DpaP[64][2];
//记录上述差值
double Deta[64];
int DpaMax;
int Sout[64][20];
double Rl[64];
//相关系数最大位置
int Max;
int main()
{
//int Key = 0b00101011;
int Key = 0;
cout << "序号 明文 二进制明文 Sout HW P\n";
for (int Nkey = 0; Nkey < 64; Nkey++) {
for (int i = 0; i < 20; i++) {
Sboxout(mingwen[i] ^ Key, Nkey,i);
}
Key++;
}
cout << "HW:key0-19\n";
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
cout << HWw[i][j] << " ";
}
cout << "\n";
}
cout << "HW:key20-39\n";
for (int i = 0; i < 20; i++) {
for (int j = 20; j < 40; j++) {
cout << HWw[j][i] << " ";
}
cout << "\n";
}
cout << "HW:key40-63\n";
for (int i = 0; i < 20; i++) {
for (int j = 40; j < 60; j++) {
cout << HWw[j][i] << " ";
}
cout << "\n";
}
cout << "HW:key60-63\n";
for (int i = 0; i < 20; i++) {
for (int j = 60; j < 64; j++) {
cout << HWw[j][i] << " ";
}
cout << "\n";
}
cout << "相关系数:R0-63:\n";
double temp=0.0;
for (int i = 0; i < 64; i++) {
Rl[i]=abs( Corr(10, Pstd, HWw[i]));
if (Rl[i] > temp) {
Max = i;
temp = Rl[i];
}
cout << setw(10) << Rl[i] << " ";
if ((i+1) % 6 == 0)
cout << "\n";
}
cout << "\nCPA攻击:\n";
cout << "最大相关:R" << Max << "=" << Rl[Max];
cout << "\n正确密钥:";
int bit[6];
int temp1 = Max;
for (int j =5; j >= 0; j--) {
bit[j] = temp1 % 2;
temp1 = temp1 / 2;
}
for (int j = 0; j < 6; j++) {
cout << bit[j];
}
Dpa();
return 0;
}
void Dpa() {
//以2为界
int Larr[20];
int Harr[20];
int Lc = 0;
int Hc = 0;
for (int i = 0; i < 20; i++) {
if (HWstd[i] < 2) {
Larr[Lc] = i;
Lc++;
}
else {
Harr[Hc] = i;
Hc++;
}
}
for (int i = 0; i < 64; i++) {
int Htemp = 0;
int Ltemp = 0;
//HW小于2,对应累加
for (int j= 0; j < Lc; j++) {
Ltemp += Ptest[i][Larr[j]];
}
//HW大于2,对应累加
for (int j = 0; j < Hc; j++) {
Htemp += Ptest[i][Harr[j]];
}
DpaP[i][0] = Ltemp*1.0/Lc;
DpaP[i][1] = Htemp*1.0/Hc;
Deta[i] = abs(DpaP[i][0] - DpaP[i][1]);
}
cout << "\nDPA攻击\n差分值:Deta0-63:\n";
for (int i = 0; i < 64; i++) {
cout <<setw(10)<< Deta[i] << " ";
if ((i + 1) % 6 == 0) {
cout << "\n";
}
}
double temp = 0.0;
for (int i = 0; i < 64; i++) {
if (Deta[i] > temp) {
DpaMax= i;
temp = Deta[i];
}
}
cout << "\n最大差分值:Deta"<<DpaMax<<"="<< Deta[DpaMax];
cout << "\n正确密钥:";
int bit[6];
int temp1 =DpaMax;
for (int j = 5; j >= 0; j--) {
bit[j] = temp1 % 2;
temp1 = temp1 / 2;
}
for (int j = 0; j < 6; j++) {
cout << bit[j];
}
}
int Sboxout(int num, int Nkey,int i) {
int HW = 0;
int P = 0;
int h = num & (0b00100000);
h = h >> 4;
int l = num & (0b00000001);
int m1 = num & (0b00000010);
m1 = m1 >> 1;
int m2 = num & (0b00000100);
m2 = m2 >> 1;
int m3 = num & (0b00001000);
m3 = m3 >> 1;
int m4 = num & (0b00010000);
m4 = m4 >> 1;
int y = l + h;
int x = m1 + m2 + m3 + m4;
//int bit[4];
int Snum = S_Box1[y][x];
Sout[Nkey][i] = Snum;
HWw[Nkey][i] = HWFun(Snum);
Ptest[Nkey][i] = HWw[Nkey][i] * 5;
//cout << " " << HWw[Nkey][i];
P = HWw[Nkey][i] * 5;
if (Nkey == 43) {
Pstd[i] = P;
HWstd[i] = HWw[Nkey][i];
}
return Snum;
}
int HWFun(int num) {
int count = 0;
int bit;
for (int i = 3; i >= 0; i--) {
bit = num % 2;
if (bit == 1)
count++;
num = num / 2;
};
return count;
}
double meanNum(int n, int num[]) {
double total=0.0;
for (int i = 0; i < n; i++) {
total = total + num[i];
}
return total / n;
}
double Corr(int n, int Pstd[], int Ptest[]) {
//int E_Pstd;
double fenzi=0.0;
double PstdMean = meanNum(n, Pstd);
double PtestdMean = meanNum(n, Ptest);
double fenmu1 = 0.0;
double fenmu2 = 0.0;
double corr = 0.0;
for (int i = 0; i < n; i++) {
fenzi += (Pstd[i] - PstdMean) * (Ptest[i] - PtestdMean);
fenmu2 += (Ptest[i] - PtestdMean)* (Ptest[i] - PtestdMean);
fenmu1 += (Pstd[i] - PstdMean) * (Pstd[i] - PstdMean);
}
corr = fenzi / (sqrt(fenmu1) * sqrt(fenmu2));
return corr;
}
结束
主要梳理了做过的有关DPA和CPA攻击的一个简单实例,真正的硬件安全检测和测信道攻击要复杂的多,安全世界无奇不有,上硬件安全设计与检测这门课,开拓了安全领域的研究视野。道路漫长,慢慢走。