参考资料:
1.计算机与软件学院实验报告管理系统资料
2.强烈推荐观看:《信息安全技术》课程微课设计
简介
什么是DES
DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。需要注意的是,在某些文献中,作为算法的DES称为数据加密算法(Data Encryption Algorithm,DEA),已与作为标准的DES区分开来。
DES的安全性
主要来源于以下几个方面:加密之初提供一个64位的密钥(去除8位奇偶校验位后,用于加密解密的是56位),而真正加密时,用到了16个48位的子密钥,子密钥的形成过程用到反反复复的移位和数组的置换,因此仅获得了最初的密钥仍然不能破解密文;同样在利用16个子密钥对64位的0、1序列加密时,也不是简单的异或,而是进行多次复杂的数组扩充,以及元素位置置换,因此即使获得了16个子密钥还是不能破解原文。
graph TD
A(64 bit 原文)
A --> B[初始置换]
B --> |K1| C[01轮加密]
C --> |K2| D[02轮加密]
D --> |K3| E[03轮加密]
E --> |K…| F[……]
F --> |K16| G[16轮加密]
G --> H[终止置换]
H --> I(64 bit 密文)
DES加密以8个字母为一个单位,每个字母由8位二进制0,1表示。64 bit plaintext 即一个单位的明文。
初始置换:把64bit明文通过IP_1置换表打乱顺序
对64bit明文进行16轮加密(每轮的的秘钥都不同K1K2…K16)
终止置换:把加密后的64bit密文通过IP_2置换表打乱顺序
初始置换
终止置换
就是把字符按照置换表格重新排顺序
如图对于一组数据
初始置换置换表(IP_1置换表)
58
50
42
34
26
18
10
2
60
52
44
36
28
20
12
4
62
54
46
38
30
22
14
6
64
56
48
40
32
24
16
8
57
49
41
33
25
17
9
1
59
51
43
35
27
19
11
3
61
53
45
37
29
21
13
5
63
55
47
39
31
23
15
7
原始数据
0
1
1
0
0
0
1
1
0
1
0
1
1
1
0
0
0
0
1
1
1
0
1
1
1
0
1
1
0
1
0
1
0
0
0
1
0
1
1
1
1
0
0
0
0
0
0
1
0
0
1
1
1
0
0
0
0
0
1
0
0
1
1
0
置换后
0
0
0
0
0
0
1
1
0
1
0
1
1
1
1
0
1
0
0
1
1
0
1
0
0
0
1
1
1
1
0
1
0
0
1
0
1
0
0
0
1
1
0
0
1
1
0
1
0
1
0
0
0
1
1
0
1
0
0
1
0
1
0
1
置换表第1个数为58,就把数据的第58位“0”放到这
置换表第2个数为50,就把数据的第50位“0”放到这
置换表第3个数为42,就把数据的第42位“0”放到这
…
置换表第64个数为7,就把数据的第7位“1”放到这
初始置换:明文按照置换表IP_1的第一次置换
终止置换: 明文被加密后按照置换表IP_2再次置换
当然两次用的置换表是不同的
16轮加密,每一轮的流程相同,但是所用到的子秘钥K不同。
我们把经过初始置换的64 bit明文记作Y0
graph TD
C{Y0}
C --> |选取左边32位| D[L]
C --> |选取右边32位| E{R}
E --> |复制一份R|F(直接作为下一轮的L)
E --> |骚操作1 E扩展置换| G[48 bit NR]
G-->|骚操作2 子秘钥K1加密| H[48 bit NR]
H-->|骚操作3 S盒压缩| I[32 bit NDS]
I-->|骚操作4 与L进行异或运算| J[32 bit NDS]
J-->K(作为下一轮的R)
Z[第一轮的加密过程]
接着换用不同的K2,K3,K4…k16完成16轮加密!
我们来看看扩展置换表和普通置换表的差别
可以发现扩展置换表有重复部分,这样R中就会有部分数据被重复使用,从而达到扩展的效果
那么被重复使用的部分是随意选的吗,它有什么规律呢吗?
由图可知他是把32位数据分为8组,对每组的首尾两位进行了扩充。
什么是异或运算呢?
1 xor 1 = 0
0 xor 0 = 0
1 xor 0 = 1
0 xor 1 = 1
我们会发现他和加法运算的区别就是,1+1=0, 这是因为二进制没有2导致的,开个玩笑哈哈哈
如下两个5位二进制序列进行异或运算
graph TD
A[A 00101]
B[B 10001]
对应位的01进行异或易得结果C
graph TD
C[C 10100]
对于32位的L与DNS异或运算也是同样的道理。
K的加密
看过“骚操作4”,我们了解到了异或运算
其实所谓的子秘钥就是一个01序列
子秘钥加密就是用01序列k1与其进行异或运算
因为此时的NR是48位,所以子秘钥K1就是48位的01序列。
16个不同的子秘钥就是16个不同的48位的01序列。
K的产生
我们知道16轮的加密需要16个不同的子密钥K,那么这16个密钥从何而来?这16个子密钥之间有什么关系呢?
原来
它是由一个密钥通过走位,咳咳…移位变换出来的
初始密钥记作Y0,它由64位01序列组成,但其中8位用于奇偶校验,所以实际用于加密的只有56位。
56位的密钥(K0)→左边为C0,右边为D0→将C0、D0移位I(i)位(i取值0-15)→C[16]、D[16]→将C[i]D[i]作为一个整体按PC-2变换,得到48位的K[i]。
graph LR
Z[子密钥的产生]
C(56 bits)
C -->|选取前28位| D[C0]
C -->|选取后28位| E[D0]
D -->| 移位I-i-位-i-分别取1到16之间的数|F[CI]
E -->| 移位I-i-位-i-分别取1到16之间的数|G[DI]
F -->x[CIDI]
G -->x[CIDI]
x -->| 整体PC_2置换 |K[48 bits]
K -->H(K1)
K -->I(K2)
K -->J(K3)
K -->Y(略)
K -->V(K14)
K -->W(K15)
K -->ZH(K16)
移位运算
就是01序列的位置向前平移
如
graph LR
B(0000011)
移位1位
graph LR
B(0000110)
移位2位
graph LR
B(0011000)
I[i]是数组I[16]中的一个数,I[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}
i取1时,I[1] = 1
C0和D0就要进行对应的移位1位运算。
像这样,i从1取到16就会得到16个子密钥
graph TD
C(48 bit NR)
C --> D[6位]
C --> E[6位]
C --> F[6位]
C --> G[6位]
C --> H[6位]
C --> I[6位]
C --> J[6位]
C --> K[6位]
D --> |s盒|M[4位]
E --> |s盒|N[4位]
F --> |s盒|O[4位]
G --> |s盒|P[4位]
H --> |s盒|Q[4位]
I --> |s盒|R[4位]
J --> |s盒|S[4位]
K --> |s盒|T[4位]
M --> W[32位]
N --> W[32位]
O --> W[32位]
P --> W[32位]
Q --> W[32位]
R --> W[32位]
S --> W[32位]
T --> W[32位]
可以看出48 bit NR 被分成了八个组 每组6位,6位被s盒搞成4位了
所以s盒部分发生了什么?
其实S盒就是一张数据表
对,长的就是这么丑
原来,
6位数的首尾两位组成了一个十进制数,作为表的 行
6位数的中间四位组成一个十进制数,作为表的 列
由行和列在表中可以确定一个值,把该值转换为4位二进制数
例
原理
DES子密钥的获得:
56位的密钥(K0)→左边为C0,右边为D0→将C0、D0移位I(i)次(i取值0-15)→C[16]、D[16]→将C[i]D[i]作为一个整体按PC-2变换,得到48位的K[i]。
利用K[i]加密的过程:
通过键盘输入8个字符,将字符对应的ASCII码值转换成0、1序列,作为待加密序列Y→通过IP将Y变成Y0→将变换后的数据Y0分为两部分,开始的32位称为L,最后的32位称为R→()将R通过E扩展成48位的序列NR→将NR与K[i](i的初始值为0,直到i=15结束)相异或结果仍然保存在NR→将NR分为8个6位长的部分,第1位到第6位称为B[0],第7位到第12位称为B[1],依此类推,第43位到第48位称为B[7→将B[J]的第1位和第6位组合为一个2位长度的变量M,M作为在S[J]中的行号。将B[J]的第2位到第5位组合,作为一个4位长度的变量N,N作为在S[J]中的列号。其中S[J]是一个有64个元素的序列,即S是一个二维数组,通过计算得来的M,N,以及当前B的序号J(J取值0-7),可以查询到S中对应的元素,并将S中的该元素,转换成二进制的四位0、1序列,存放在NDS中相应的四位中→将NDS与L相异或,结果仍然保留在NDS中→将R值赋给L,将NDS赋给R,回到()处开始循环→将最后一次得到的L、R作为一个整体利用序列IP_1扩展成64位的加密数据M。
解密的过程:
M利用逆IP_1变换得到L、R→()R赋值给tL,L值赋值给tR→tR按E扩展为NR→NR与K[i](i初始值为15,以后递减直到0结束)异或,结果保存在NR→利用S查询的方法得到NDS→将tL与NDS相异或,结果保留在tL中→将tL赋值给L,将tR赋值给R,回到()处开始循环→将最终的L、R按照逆变换IP得到原数据A。
#include<iostream>
#include<cmath>
using namespace std;
/*=======================Loop_Move循环左移============================*/
void loop_move(int *p,int i)//p指向需要移位数组
{
if(i == 1)//左移1位
{
int temp;
temp = *(p+0);
for(int k = 0 ;k < 27; k++)
{
*(p+k) = *(p+k+1);
}
*(p+27) = temp;
}
else//左移2位
{
int temp0;
int temp1;
temp0 = *(p + 0);
temp1 = *(p + 1);
for(int n = 0 ;n < 27 ; n++)
{
*(p + n ) = *(p + n + 2);
}
*(p +26) = temp0;
*(p +27) = temp1;
}
}
/*=========================x_or异或运算============================*/
void x_or(int *p1,int *p2,int num)//num为数组内的数据个数
{
int temp = 0;
for(int i = 0; i < num; i++)
{
temp = *(p1+i) + *(p2+i);
temp = temp - (temp/2)*2;
*(p1+i) = temp;
}
}
/*=======================Dcm_Binary_Swap十进制转为二进制============================*/
void db_swap(int dcm,int *p )
{
int temp1 = dcm;
int temp2;
for(int i = 3;i >= 0;i--)
{
temp2 = temp1/2;
temp1 = temp1 - temp2*2;
*(p+i) = temp1;
temp1 = temp2;
}
}
/*==================根据后一次L,R推出前一次L,R====================*/
void getdt1(int E[],int S[][64],int *k,int *L,int *R)//利用后一次LR必要的密码信息,得到上一次的LR
{
int i,j;
int NR[48];
int NDS[32];
int tR[32];
int tL[32];
int h,l,temp;
for(i=0;i<=31;i++)
{
tR[i]=*(L+i);//本轮的左边为上一轮末尾的右边
}
for(i=0;i<=31;i++)
{
tL[i]=*(R+i);//把与L异或运算后的NDS赋值给tL
}
//对R进行加密从而获得“新鲜的(没有和L异或运算的)”NDS
for(i=0;i<=47;i++)
{
NR[i]=tR[E[i]];
}
x_or(NR,k,48);
for(j=0;j<=7;j++)
{
h=NR[0+6*j]*2+NR[5+6*j];
l=NR[1+6*j]*8+NR[2+6*j]*4+NR[3+6*j]*2+NR[4+6*j];
temp=S[j][h*16+l];
db_swap(temp,(NDS+j*4));
}
x_or(tL,NDS,32);//tL(L与NDS异或运算的结果)再次与NDS异或,得到L
for(i=0;i<=31;i++)
{
*(L+i)=tL[i];
}
for(i=0;i<=31;i++)
{
*(R+i)=tR[i];
}
}
/*=====================输出函数,把二进制转为char字符==================*/
void showt(int a[])//输出a,0、1数组代表的八个字符
{
char c;
int temp;
int i,j,n;
for(i=0;i<=7;i++)
{
temp=0;
for(j=0;j<=7;j++)
{
temp=temp+a[i*8+j]*(pow(2,(7-j))); //8位二进制转为十进制
}
c=temp;//把temp转为字符型
cout<<c<<endl;
}
}
class des2;//加密
class ides;//解密
/*=================================产生16个子秘钥======================================*/
class des//用来产生16个子密钥
{
private:
int K0[56];//最原始的密码,没有奇偶校验位。
int C0[28],D0[28];//第一次将密码分组
int C[16][28],D[16][28];//以后将密码分组
int K[16][48];//最终的密码
int pc2[48];
int I[16];//移位的位数
public:
des();
friend des2;
friend ides;
};
des::des()
{
//setI()
int tempI[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
for(int n=0;n<=15;n++)
{
I[n]=tempI[n];
}
//setpc2()
int temppc2[48]={14,17,11,24,1,5,3,28,15,6,21,10,23,19,12,4,26,8,16,7,27,20,13,2,
41,52,31,37,47,55,30,40,51,45,33,48,44,49,39,55,34,53,46,42,50,36,29,32};
for( int n=0;n<=47;n++)
{
pc2[n]=temppc2[n];
}
//setK0()
int tempK0[56]={1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,
0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0};
for( int n=0;n<=55;n++)
{
K0[n]=tempK0[n];
}
//getC0()
for( int n=0;n<=27;n++)
{
C0[n]=K0[n];//C0等于K0的前半数据
}
//getD0()
for( int n=0;n<=27;n++)
{
D0[n]=K0[n+28];//D0等于K0的后半数据
}
//getC()
int tempC[28];
for( int n=0;n<=27;n++)
{
tempC[n]=C0[n];
}
for(int i=0;i<=15;i++)
{
loop_move(tempC,I[i]);//将C0移位I(i)
for(int n=0;n<=27;n++)
{
C[i][n]=tempC[n];
}
}
//getD()
int tempD[28];
for(int n=0;n<=27;n++)
{
tempD[n]=D0[n];
}
for(int i=0;i<=15;i++)
{
loop_move(tempD,I[i]);//将D0移位I(i)
for(int n=0;n<=27;n++)
{
D[i][n]=tempD[n];
}
}
//getK()
int CD[56];
for( int n=0;n<=15;n++)//把C0和D0合起来
{
for( int i=0;i<=27;i++)
{
CD[i]=C[n][i];
}
for(int i=28;i<=55;i++)
{
CD[i]=D[n][i-28];
}
for(int i=0;i<=47;i++)
{
K[n][i]=CD[pc2[i]];
}
}
}
/*=======================加密============================*/
//giveM 加密算法
class des2
{
public:
des2();
void giveM(int *p);
private:
char c[8];//原文
int Y0[64];//原文的二进制形式
int IP[64];//IP置换表
int S[8][64];//S盒
int E[48];//扩充表
int IP_1[64];//IP置换表
int L[32];//Y 的左半部分
int R[32];//Y 的右半部分
int NR[48];//用E扩充后的bit
int NDS[32];//S盒压缩后的bit
int Y[64];//被IP置乱后的Y0
int M[64];//密文
int K[16][48];//16个子秘钥
};
des2::des2()
{ int i,j;
int temp1,temp2;
cout<<"输入内容(8个符号):"<<endl;//DES加密以8个字符为一组
for(i=0;i<=7;i++){cin>>c[i];}
for(i=0;i<=7;i++)
{
temp1=c[i];//字符转换为int型ASCII,进而转换成二进制
for(j=0;j<=7;j++)//8个十进制数转换为64个二进制bit
{
temp2=temp1/2;
Y0[i*8+7-j]=temp1%2;
temp1=temp2;
}
}
//setS() 八个S黑盒的具体内容
int tempS[8][64]={
{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},
{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9},
{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12},
{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14},
{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3},
{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13},
{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12},
{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11},
};
for(i=0;i<=7;i++)
{
for(j=0;j<=63;j++)
{
S[i][j]=tempS[i][j];
}
}
//setE() 用于 32位——>48位 扩充的E置换表
int tempE[48]={0,1,2,3,4,5,4,5,6,7,8,9,8,9,10,11,12,13,12,13,14,15,16,17,16,17,18,19
,20,21,20,21,22,23,24,25,24,25,26,27,28,29,28,29,30,31,0,1};
for(i=0;i<=47;i++)
{
E[i]=tempE[i];
}
//setIP_1() 置换表
int tempIP_1[64]={40,8,48,16,56,24,0,32,39,7,47,15,55,23,63,31,38,6,46,14,54,22,62,
30,37,5,45,13,53,21,61,29,36,4,44,12,52,20,60,28,35,3,43,11,51,19,59,27,34,2,42,10,50,18,58,26,33,1,41,9,49,17,57,25};
for(i=0;i<=63;i++)
{
IP_1[i]=tempIP_1[i];
}
//setIP() 置换表
int tempIP[64]={19,50,42,34,11,18,10,2,60,51,44,36,28,20,12,7,62,54,46,38,30,17,14,6,0,
56,48,40,32,24,16,8,57,49,41,33,25,22,9,1,59,52,43,35,27,58,26,3,61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,4};
for(i=0;i<=63;i++)
{
IP[i]=tempIP[i];
}
//getKLR() 获取16个子秘钥
int n;
int h,l;
int temp;
des jm;//定义“用于产生16个子秘钥的”对象
for(i=0;i<=15;i++)
{
for(j=0;j<=47;j++)
{
K[i][j]=jm.K[i][j];
}
}
//getM() 产生密文
for(i=0;i<=63;i++)
{
Y[i]=Y0[IP[i]];//将原始数据经过IP进行第一次置乱
}
for(i=0;i<=31;i++)//Y 的左半部分
{
L[i]=Y[i];
}
for(i=0;i<=31;i++)//Y 的右半部分
{
R[i]=Y[i+32];
}
for(n=0;n<=15;n++)
{
for(i=0;i<=47;i++)
{
NR[i]=R[E[i]];//用E把R扩充为48位
}
x_or(NR,jm.K[n],48);//用子秘钥K[n]对NR加密(总共加密15轮哦)
for(j=0;j<=7;j++)//S盒压缩处理(6——>4)
{
h=NR[0+6*j]*2+NR[5+6*j];//首位组成十进制数作为表的 行
l=NR[1+6*j]*8+NR[2+6*j]*4+NR[3+6*j]*2+NR[4+6*j];//中间组成十进制数作为表的 列
temp=S[j][h*16+l];//对应的十进制值
db_swap(temp,(NDS+j*4));//把1个十进制数转换为4个二进制bit
}
x_or(NDS,L,32);//R被加密为NDS后与L异或运算
for(i=0;i<=31;i++)//R作为下一轮加密的L
{
L[i]=R[i];}
for(i=0;i<=31;i++)//L作为下一轮加密的R
{
R[i]=NDS[i];
}
}
//把经过16轮加密后的密文L、R放一块,最后再赋值给M
int tempM[64];
for(i=0;i<=31;i++)
{
tempM[i]=L[i];
}
for(i=32;i<=63;i++)
{
tempM[i]=R[i-32];
}
for(i=0;i<=63;i++)
{
M[i]=tempM[IP_1[i]];
}
}
void des2::giveM(int *p)//把密文赋值给传入的地址
{
int i;
for(i=0;i<=63;i++)
{
*(p+i)=M[i];
}
}
/*========================================解密=================================*/
class ides
{
public:
int E[48];
int S[8][64];
int IP_1[64];
int IP[64];
int K[16][48];
int A[64];
ides();
void getA(int M[]);
void giveA(int *p);
};
ides::ides()
{
int i,j;
//setE()
int tempE[48]={0,1,2,3,4,5,4,5,6,7,8,9,8,9,10,11,12,13,12,13,14,15,16,17,16,17,18,19,
20,21,20,21,22,23,24,25,24,25,26,27,28,29,28,29,30,31,0,1};
for(i=0;i<=47;i++)
{
E[i]=tempE[i];
}
//setS()
int tempS[8][64]={{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},
{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9},
{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12},
{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14},
{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3},
{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13},
{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12},
{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11},
};
for(i=0;i<=7;i++)
{
for(j=0;j<=63;j++)
{
S[i][j]=tempS[i][j];
}
}
//getIP_1
int tempIP_1[64]={40,8,48,16,56,24,0,32,39,7,47,15,55,23,63,31,38,6,46,14,54,22,62,30,
37,5,45,13,53,21,61,29,36,4,44,12,52,20,60,28,35,3,43,11,51,19,59,27,34,2,42,10,50,18,58,26,33,1,41,9,49,17,57,25};
for(i=0;i<=63;i++)
{
IP_1[i]=tempIP_1[i];
}
//setIP
int tempIP[64]={19,50,42,34,11,18,10,2,60,51,44,36,28,20,12,7,62,54,46,38,30,17,14,6,0,
56,48,40,32,24,16,8,57,49,41,33,25,22,9,1,59,52,43,35,27,58,26,3,61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,4};
for(i=0;i<=63;i++)
{
IP[i]=tempIP[i];
}
//getK
des jm;
for(i=0;i<=15;i++)
{
for(j=0;j<=47;j++)
{
K[i][j]=jm.K[i][j];
}
}
}
void ides::getA(int M[])
{
int i,j;
int nM[64];
int L[32],R[32];
for(i=0;i<=63;i++)
{
nM[IP_1[i]]=M[i];//还原被IP_1置乱的密文
}
for(i=0;i<=31;i++)
{
L[i]=nM[i];
}
for(j=0;j<=31;j++)
{
R[j]=nM[j+32];
}
int tA[64];
for(i=15;i>=0;i--)
{getdt1(E,S,K[i],L,R);}//还原16轮的加密
cout<<endl;
//把L和R合一块
for(i=0;i<=31;i++)
{
tA[i]=L[i];
}
for(i=32;i<=63;i++)
{
tA[i]=R[i-32];
}
for(i=0;i<=63;i++)
{
A[IP[i]]=tA[i];//还原第一次的置乱,获得原文的二进制ASCII bit
}
}
void ides::giveA(int *p)//把原文赋值给*P
{
int i;
for(i=0;i<=63;i++)
{
*(p+i)=A[i];
}
}
int main()
{
int miwen[64];
int jimizhihou[64];
des2 jm2;
jm2.giveM(miwen);
cout<<endl;
cout<<"[密文]:"<<endl;
showt(miwen);
ides am;
am.getA(miwen);
am.giveA(jimizhihou);
cout<<endl;
cout<<"[密文]破解结果:"<<endl;
showt(jimizhihou);
cout<<endl;
return 0;
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章