如何实现C语言的DES加密算法实现,请关注
本人能力有限,这个仅供参考,请各位注意
*这仅是DES的第一轮加密
*输入明文:computer#
*输入密文:program#
*书本的错误:
*1.密钥k经过置换后得到的D0最后一位有错误,应该为1 (这个错误不影响往后的结果)
*2.通过8个s盒得到32位的序列第二组前四位有错,应该为1101,而不是0011
*3.往后的结果均由上2的错误导致
********************************************/
/********DES密码的加密过程******************
*1.将字母转化为二进制数(明文&密文)分成两组完成
*2.对明文m进行初始IP置换完成
*3.对密钥k进行密钥置换完成
*4.对密钥k进行压缩置换完成
*5.对R0进行扩展变换32->48完成
*6.结果和k进行异或运算完成
*7.将结果分成8组,通过8个s盒完成
*8.对s盒的输出序列进行P置换完成
*9.对p置换的结果与L0进行异或运算完成
********************************************/
#include
int ip[] = {//IP置换
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
};
int jiou[] = {
7,15,23,31,39,47,55,63//进行密钥添加奇偶校验位使用
};
int ki[] = {//密钥置换
57,49,41,33,25,17, 9, 1,58,50,42,34,26,18,
10, 2,59,51,43,35,27,19,11, 3,60,52,44,36,
63,55,47,39,31,23,15, 7,62,54,46,38,30,22,
14, 6,61,53,45,37,29,21,13, 5,28,20,12, 4
};
int kyasuo[]= {//对密钥进行压缩置换
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,56,34,53,46,42,50,36,29,32
};
int mkuozhan[]= {
32, 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,32, 1
};
int s[8][4][16] = {//8个s盒
{
{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, 4,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},
{10, 6, 9, 0,12,11, 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}
}
};
int p[32] = {//最后的p置换
16, 7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10,
2, 8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25
};
void main()
{
char mingwen1[100];
int mingwen2[100];
int tempmingwen[100];
int L0[32],R0[32];
int R48[48];
char miyue1[100];
int miyue2[100];
int tempmiyue[100];
int C0[28],D0[28];
int yihuo[48];//存放R0与K1异或的结果
int sheD; //存放经过s盒之后的十进制结果
int sheB[8][4];//存放经过s盒之后的二进制结果
int she[32];//对s盒中的数据进行合并,存放经过s盒的结果
int hang,lie;//存放s盒的行列序号
int p2[32];//存放经过p置换后的结果
int c,d;//存放C0[0]和D0[0]
int i,j;//i,j作为循环使用
int icount1,icount2,k;
int temp;
//__________________________明文输入__________________________________________________________________________________________________
k=0;
printf("请输入明文(以'#'号结尾):\n");
for(i=0; i<100; i++)
{
scanf("%c",&mingwen1[i]);
if('#' == mingwen1[i])
{
icount1 = i;
goto loop1;
}
}
loop1:for(i=0;i<=icount1;i++)
{
for(j=7;j>=0;j--)
{
temp=mingwen1[i]&(1<
if(0 == temp)
{
mingwen2[k]=0;
k++;
}
else
{
mingwen2[k]=1;
k++;
}
}
}
//_________________________密钥输入___________________________________________________________________________________________________
k=0;
fflush(stdin);//清除缓冲区内的数据,如果不加上,则miwen[0]会多出一个LF(换行符)!!!
printf("请输入密钥(以'#'号结束):\n");
for(i=0; i<100; i++)
{
scanf("%c",&miyue1[i]);
if('#' == miyue1[i])
{
icount2 = i;
goto loop2;
}
}
loop2:for(i=0;i<=icount2;i++)
{
for(j=7;j>=0;j--)
{
temp=miyue1[i]&(1<
if(0 == temp)
{
miyue2[k]=0;
k++;
}
else
{
miyue2[k]=1;
k++;
}
}
}
//**********************************************************
printf("\n\nm = ");
for(i=0;i<8*icount1;i++)
{
printf("%d",mingwen2[i]);
if(i== 7||i==15||i==23||i==39||i==47||i==55||i==63)
{printf(" ");}
if(i==31)
{printf("\n");printf(" ");}
}
printf("\nk = ");
for(i=0;i<8*icount2;i++)
{
printf("%d",miyue2[i]);
if(i== 7||i==15||i==23||i==39||i==47||i==55||i==63)
{printf(" ");}
if(i==31)
{printf("\n");printf(" ");}
}
printf("\n");
//**********************************************************/
//____________________至此二进制的明文存放在mingwen2[]中_____________________________________________________________________________
//________________________进行明文的初始置换IP_________________________________________________________________________________________________
fflush(stdin);//清除缓冲区内的数据
for(i=0;i<8*icount1;i++)
{
tempmingwen[i] = mingwen2[ip[i]-1];
}
//________________________置换IP后的结果存放在tempmingwen[i]中__________________________________________________________________________
//________________________把明文结果存放到L0和R0中______________________________________________________________________________________
fflush(stdin);//清除缓冲区内的数据
for(i=0;i<64;i++)
{
if(i<32) {L0[i]=tempmingwen[i];}
else {R0[i-32]=tempmingwen[i];}
}
//**************************************
printf("\nm经过IP置换后得到:\n");
printf("L0: ");
for(i=0;i<32;i++)
{
printf("%d",L0[i]);
if(i== 7||i==15||i==23||i==31)
{printf(" ");}
}
printf("\nR0: ");
for(i=0;i<32;i++)
{
printf("%d",R0[i]);
if(i== 7||i==15||i==23||i==31)
{printf(" ");}
}
printf("\n");
//**************************************/
//_______________________对密文进行添加奇偶校验位_______________________________________________________________________________________
fflush(stdin);//清除缓冲区内的数据
for(i=0;i<8;i++)
{
j=56+i;
while(j>=jiou[i])
{
miyue2[j+1]=miyue2[j];
j--;
}
if(i==0 || i==2 || i==4 || i==6) {miyue2[jiou[i]]=0;}
else {miyue2[jiou[i]]=1;}
}
/**********************************************************
for(i=0;i<64;i++)
{
printf("%d",miyue2[i]);
if(i== 7||i==15||i==23||i==31||i==39||i==47||i==55||i==63)
{printf(" ");}
}
**********************************************************/
//_________________________对密文进行密钥置换___________________________________________________________________________________________________
fflush(stdin);//清除缓冲区内的数据
for(i=0;i<56;i++)
{
tempmiyue[i]=miyue2[ki[i]-1];
}
/*********************************
printf("\n\n");
for(i=0;i<56;i++)
{
printf("%d",tempmiyue[i]);
if(i== 7||i==15||i==23||i==31||i==39||i==47||i==55||i==63)
{printf(" ");}
}
*********************************/
fflush(stdin);//清除缓冲区内的数据
for(i=0;i<56;i++)
{
if(i<28) {C0[i]=tempmiyue[i];}
else {D0[i-28]=tempmiyue[i];}
}
//**************************************
printf("\n密钥k经过置换后得到:");
printf("\nC0: ");
for(i=0;i<28;i++)
{
printf("%d",C0[i]);
if(i== 7||i==15||i==23)
{printf(" ");}
}
printf("\nR0: ");
for(i=0;i<28;i++)
{
printf("%d",D0[i]);
if(i== 7||i==15||i==23)
{printf(" ");}
}
printf("\n");
//**************************************/
//_________________________分别对C0和D0进行循环左移操作____________________________________________________________________________________
c = C0[0];
d = D0[0];
for(i=0;i<27;i++)
{
C0[i] = C0[i+1];
}
C0[28] = c;
for(i=0;i<27;i++)
{
D0[i] = D0[i+1];
}
D0[28] = d;
//__________________________对C0和D0进行合并存入miyue2[]中______________________________________________________________________________
fflush(stdin);//清除缓冲区内的数据
for(i=0;i<56;i++)
{
if(i<28) {miyue2[i]=C0[i];}
else {miyue2[i]=D0[i-28];}
}
//______________________________________________________________________________________-
fflush(stdin);//清除缓冲区内的数据
for(i=0;i<48;i++)
{
tempmiyue[i] = miyue2[kyasuo[i]-1];
}
//**************************************
printf("\n循环左移一位后经过密钥置换得到48位子密钥:\n");
for(i=0;i<48;i++)
{
printf("%d",tempmiyue[i]);
if(i== 7||i==15||i==31||i==39||i==47)
{printf(" ");}
if(i==23)
{printf("\n");}
}
//**************************************/
fflush(stdin);//清除缓冲区内的数据
for(i=0;i<48;i++)
{
R48[i]=R0[mkuozhan[i]-1];
}
//***************************************
printf("\n\nR0经过扩展变换得到的48位序列为:\n");
for(i=0;i<48;i++)
{
printf("%d",R48[i]);
if(i== 7||i==15||i==31||i==39||i==47)
{printf(" ");}
if(i==23)
{printf("\n");}
}
//**************************************/
//______________________R0与K1异或______________________________________________________________
fflush(stdin);//清除缓冲区内的数据
for(i=0;i<48;i++)
{
yihuo[i] = R48[i]^tempmiyue[i];
}
//______________________结果存放到yihuo[]数组中_________________________________________________
//***************************************
printf("\n\n结果再和k1进行异或运算,得到的结果为:\n");
for(i=0;i<48;i++)
{
printf("%d",yihuo[i]);
if(i== 7||i==15||i==31||i==39||i==47)
{printf(" ");}
if(i==23)
{printf("\n");}
}
//**************************************/
//_______________________通过8个s盒的到32位的序列_______________________________________________
fflush(stdin);//清除缓冲区内的数据
for(i=0;i<8;i++)
{
k=0;//清除k的值
hang=yihuo[(1+(i*6))-1]*2 + yihuo[(6+(i*6))-1];
lie =yihuo[(2+(i*6))-1]*8 + yihuo[(3+(i*6))-1]*4 + yihuo[(4+(i*6))-1]*2 + yihuo[(5+(i*6))-1];
sheD=s[i][hang][lie];
for(j=3;j>=0;j--)
{
temp=sheD&(1<
if(0 == temp)
{
sheB[i][k]=0;
k++;
}
else
{
sheB[i][k]=1;
k++;
}
}
}
//______________________将二维数组sheB[][]中的内容转存到一维数组she中,方便以后的计算___________
fflush(stdin);//清除缓冲区内的数据
k=0;
for(i=0;i<8;i++)
{
for(j=0;j<4;j++)
{
she[k]=sheB[i][j];
k++;
}
}
//*************************************
printf("\n\n通过8个s盒得到32位的序列为:\n");
for(i=0;i<32;i++)
{
printf("%d",she[i]);
if(i== 7||i==15||i==23||i==31)
{printf(" ");}
}
printf("\n");
//*************************************/
//______________________对s盒的输出序列进行p置换__________________________________________________________
fflush(stdin);//清除缓冲区内的数据
for(i=0;i<32;i++)
{
p2[i]=she[p[i]-1];
}
//*************************************
fflush(stdin);//清除缓冲区内的数据
printf("\n对s盒的输出序列进行p置换,得到\n");
for(i=0;i<32;i++)
{
printf("%d",p2[i]);
if(i== 7||i==15||i==23||i==31)
{printf(" ");}
}
//*************************************/
//______________________p置换之后和L0进行异或运算_______________________________________________________________________________
fflush(stdin);//清除缓冲区内的数据
for(i=0;i<32;i++)
{
p2[i]=L0[i]^p2[i];
}
//______________________L0和R0交换________________________________________________________________________________________________________
for(i=0;i<32;i++)
{
L0[i]=R0[i];
R0[i]=p2[i];
}
//*************************************
printf("\n\n经过以上操作,得到进过第一轮加密的结果序列为:\n");
printf("L0: ");
for(i=0;i<32;i++)
{
printf("%d",L0[i]);
if(i== 7||i==15||i==23||i==31)
{printf(" ");}
}
printf("\n");
printf("R0: ");
for(i=0;i<32;i++)
{
printf("%d",R0[i]);
if(i== 7||i==15||i==23||i==31)
{printf(" ");}
}
printf("\n");
//*************************************/
}