视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
实现DES 分组密码算法的加解密
2025-09-28 00:36:40 责编:小OO
文档
实     验    报     告

课程:密码学  班级:     姓名:     学号:

成绩:              指导教师:     实验日期:2011/5/25

实验密级:        预习程度:         实验时间:12:50-15:20

仪器组次:  18         必修/选修:必修     实验序号:4

实验名称: 实现DES 分组密码算法的加解密                                                         

实验目的与要求:1、掌握DES 分组密码算法的软件实现方法;

2、复习DES 分组密码算法设计的基本原理;

3、能用DES 分组密码算法实现已知明文的加解密                                                        

                                                                        

                                                                        

                                                                        

实验仪器:

名称型号数量
计算机Lenovo1
一、实验要求

1、求主密钥的扩展密钥前,先输出使用的PC-1 置换和PC-2 置换;

2、对明/密文文件用DES 算法进行加/解密前,先输出确定使用的S 盒和有关置换表;

3、“确定主密钥的扩展密钥”和“对明/密文文件的加/解密”分别编写两个模块,如果时

间不够,可以任选一个模块;

4、确定扩展密钥前,先指出是加密密钥还是解密密钥;

5、密钥扩展的移位的位数可以先添表,但最后一轮移位完后,必须回到初始值c0d0。

6、主密钥长度与明文相一致,需要忽略校验位;

7、能完成任意给定的一个明/密文文件的加/解密;

8、加解密结果正确。

二、实验内容与步骤

下面是程序的部分代码

int main()

{                           

char MingWen[104];          

char target[8];             

char InputKey[8];           

int text[];               

int text_ip[];            

int L0[32],Li[32];          

int R0[32],Ri[32];

int RE0[48];                

int key[];               

int keyPC1[56];             

int A[28];                 

int B[28];

int keyAB[56];             

int K[16][48];              

int RK[48];                 

int RKS[8];                 

int SP[32];                

int RKSP[32];              

int text_end[];           

int text_out[14][];       

char init[9]={"HTmadeit"};  

int CBC[];

int result[13][];

int H[208];

char MiWen[208];

int C[832];

int M[13][8];

char choice;

int t;

int i,j;

int k,l,m,n;

int r[8],c[8];

int flag=1;

printf("欢迎使用DES加密解密\\n\\n");

while(flag)

{printf("A加密,B解密,请选择:\\n");

scanf("%c",&choice);

while(choice!='A'&&choice!='B'&&choice!='a'&&choice!='b')

{printf("对不起,您的输入不合法。请选择A或B,A表示加密,B表示解密。\\n");

 scanf("%c",&choice);

}

getchar();

 printf("请输入8位密钥:\\n");

gets(InputKey);

while(InputKey[7]=='\\0'||InputKey[8]!='\\0')

{

 printf("您输入的密钥位数有误,请重新输入8位密钥:\\n");

 gets(InputKey);

}

for(i=0;i<8;i++)

{

 int a[8]={0,0,0,0,0,0,0,0};

 m=InputKey[i];

 for(j=0;m!=0;j++)

 {

  a[j]=m%2;

  m=m/2;

 }

for(j=0;j<8;j++)

    key[(i*8)+j]=a[7-j];

}

for(i=0;i<56;i++)

  keyPC1[i]=key[PC1[i]-1];

for(i=0;i<28;i++) {

  A[i]=keyPC1[i];

  B[i]=keyPC1[i+28];

 }

for(t=0;t<16;t++)

 {

  if(move[t]==1)      

  {

   n=A[0];

for(i=0;i<27;i++)

    A[i]=A[i+1];

   A[27]=n;

   n=B[0];

for(i=0;i<28;i++)

   

      else  

for(i=0;i<8;i++)

   target[i]=MingWen[i+(8*l)];

  

for(i=0;i<8;i++)

   {

   int a[8]={0,0,0,0,0,0,0,0};

   m=target[i];

   for(j=0;m!=0;j++)

    {a[j]=m%2;

    m=m/2;

    }

for(j=0;j<8;j++)

   text[(i*8)+j]=a[7-j];

   }

//for(i=0;i<;i++)

      //printf("%d,",text[i]);

      //printf("\\n");

//for(i=0;i<;i++)

      //printf("%d,",text_out[l][i]);

      //printf("\\n");

      for(i=0;i<;i++)              //CBC模式下前一分组的密文异或当前分组

       text[i]=text_out[l][i]^text[i];

//for(i=0;i<;i++)

      //printf("%d,",text[i]);

      //printf("\\n");

      //对每个text进行DES加密

      for(i=0;i<;i++)          //进行初始换位

       text_ip[i]=text[IP[i]-1];

                            

      for(i=0;i<32;i++)         //分成左右两部分,各32位

   {

    L0[i]=text_ip[i];

    R0[i]=text_ip[i+32];

   }

  

//for(i=0;i<32;i++)

   //  printf("%d,",L0[i]);

//for(i=0;i<32;i++)

   //  printf("%d,",R0[i]);

 

      //十六次迭代

for(t=0;t<16;t++)

   {

    for(i=0;i<48;i++)        //将右半部分通过扩展换位表E从32位扩展成48位

    RE0[i]=R0[E[i]-1];

    //printf("RE0\\n");

//for(i=0;i<48;i++)

    //printf("%d,",RE0[i]);

     for(i=0;i<48;i++)      //RE与K异或运算

     RK[i]=RE0[i]^K[t][i];

    //printf("\\n");

//for(i=0;i<48;i++)

    //printf("%d,",RK[i]);

    for(i=0;i<8;i++)        //将R和K异或运算的结果通过S位移表

    {

     r[i]=RK[(i*6)+0]*2+RK[(i*6)+5];

     c[i]=RK[(i*6)+1]*8+RK[(i*6)+2]*4+RK[(i*6)+3]*2+RK[(i*6)+4];

    }

    RKS[0]=S1[r[0]][c[0]]; 

    RKS[1]=S2[r[1]][c[1]];

    RKS[2]=S3[r[2]][c[2]];

    RKS[3]=S4[r[3]][c[3]];

    RKS[4]=S5[r[4]][c[4]];

    RKS[5]=S6[r[5]][c[5]];

    RKS[6]=S7[r[6]][c[6]];

    RKS[7]=S8[r[7]][c[7]];

    for(i=0;i<8;i++)        //把结果转成32位二进制储存在数组SP中

    {

     int b[4]={0,0,0,0};

     m=RKS[i];

     for(j=3;m!=0;j--)

     {

      b[j]=m%2;

      m=m/2;

     }

for(j=0;j<4;j++)

      SP[j+(i*4)]=b[j];

    }

    for(i=0;i<32;i++)        //将二进制结果再经过一个P盒换位

     RKSP[i]=SP[P[i]-1];

    for(i=0;i<32;i++)        //与前一次的左部异或运算,得到本次迭代的右部

     Ri[i]=L0[i]^RKSP[i];

for(i=0;i<32;i++)

    {

     L0[i]=R0[i];

     R0[i]=Ri[i];

    }

   }

  

else if(choice=='B'||choice=='b')

{

 printf("请输入密文内容:\\n");

 gets(MiWen);

for(i=0;i<208;i++)

  H[i]=0;

        for(i=0;MiWen[i]!='\\0';i++)                  //将十六进制密文转化成十进制存放在数组H中

 {

if(MiWen[i]>='0'&&MiWen[i]<='9')

   H[i]=MiWen[i]-'0';

else if(MiWen[i]>='A'&&MiWen[i]<='F')

                        H[i]=MiWen[i]-'A'+10;

else if(MiWen[i]>='a'&&MiWen[i]<='f')

                        H[i]=MiWen[i]-'a'+10;

                else 

  {

   printf("请输入用十六进制表示的密文内容:\\n");

             gets(MiWen);

                        i=0;

  }

 }

        n=i;                          //密文有n个字符

 if(n%16!=0)

 {

  printf("对不起,您输入的密文不正确,请确认密文的内容,密文的字符数应是16的倍数。\\n");

  printf("请输入密文内容:\\n");

                gets(MiWen);

for(i=0;i<208;i++)

   H[i]=0;

  for(i=0;MiWen[i]!='\\0';i++)                  //将十六进制密文转化成十进制存放在数组H中

  {

if(MiWen[i]>='0'&&MiWen[i]<='9')

    H[i]=MiWen[i]-'0';

else if(MiWen[i]>='A'&&MiWen[i]<='F')

    H[i]=MiWen[i]-'A'+10;

else if(MiWen[i]>='a'&&MiWen[i]<='f')

    H[i]=MiWen[i]-'a'+10;

  }

 }

 for(i=0;i {

  int he[4]={0,0,0,0};

  for(j=3;H[i]!=0;j--)

  {

   he[j]=H[i]%2;

                        H[i]=H[i]/2;

  }

for(j=0;j<4;j++)

   C[j+(i*4)]=he[j];

 }

//for(i=0;i<130;i++)

 //    printf("%d,",C[i]);

        //printf("\\n");

 k=n/16;

for(l=0;l {

  for(i=0;i<;i++)           //将每个分组对应的位二进制密文放到text_out中

   text_out[l+1][i]=C[i+(l*)];            

//for(i=0;i<;i++)

                //   printf("%d,",text_out[l][i]);

                //printf("\\n");

                //对每个text进行DES解密

 

                for(i=0;i<;i++)          //进行初始换位

   text_ip[i]=text_out[l+1][IP[i]-1];

                            

//for(i=0;i<;i++)

                //printf("%d,",text_ip[i]);

                //printf("\\n");

  for(i=0;i<32;i++)         //分成左右两部分,各32位

  {

   L0[i]=text_ip[i];

   R0[i]=text_ip[i+32];

  }

//for(i=0;i<32;i++)

               //  printf("%d,",L0[i]);

//for(i=0;i<32;i++)

               //  printf("%d,",R0[i]);

 

  

  

  //CBC模式下的解密

  for(i=0;i<;i++)          //前一分组的密文异或当前分组所得明文的二进制放到result中

   result[l][i]=text_out[l][i]^text[i];

          }

          for(i=0;i<(n/16);i++)           //将二进制转成十进制

for(j=0;j<8;j++)

    M[i][j]=result[i][(j*8)+0]*128+result[i][(j*8)+1]*+result[i][(j*8)+2]*32+result[i][(j*8)+3]*16+result[i][(j*8)+4]*8+result[i][(j*8)+5]*4+result[i][(j*8)+6]*2+result[i][(j*8)+7];

   printf("您的文件经过DES解密后的明文是:\\n");

for(i=0;i<(n/16);i++)

for(j=0;j<8;j++)

     printf("%c",M[i][j]);

    printf("\\n\\n\\n");

  }

flag=0;

printf("是否继续?\\n");

printf("Y继续,N退出,请选择:\\n");

scanf("%c",&choice);

while(choice!='Y'&&choice!='N'&&choice!='y'&&choice!='n')

{printf("对不起,您的输入不合法。请选择Y或N,Y表示继续使用本程序,N表示退出。\\n");

 scanf("%c",&choice);

}

getchar();

if(choice=='Y'||choice=='y')

   flag=1;

}

}

三、实验体会

在这次实验中我学到很多东西,了解如何实现DES算法。

首先,和以前实验相比,这次实验比较难,程序代码很长,需要花大工夫才能理解,最后还是在同学的帮助下程序才实现。

就程序本身来说,由于步骤比较多,所以逻辑要很清楚,在明密文的转换中产生各种错误,需要耐心细心检查。

通过这次实验使我对知识本身有着更深的了解,希望以后实验能学到更多知识。下载本文

显示全文
专题