CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

高手进,请教DES算法,帮忙看看,急啊!分不够在加!!解决后在送100

楼主xingfuniao(幸福鸟)2006-06-01 00:39:57 在 C/C++ / C语言 提问

int   DES(unsigned   char   *bufferin,unsigned   char   *bufferout,   unsigned   char   *key,long   mode)  
  {  
  //密钥变换为56字节(去掉校验位)  
  static   unsigned   char   pc1[56]   =   {  
  56,   48,   40,   32,   24,   16,   8,    
  0,   57,   49,   41,   33,   25,   17,    
  9,   1,   58,   50,   42,   34,   26,    
  18,   10,   2,   59,   51,   43,   35,    
  62,   54,   46,   38,   30,   22,   14,    
  6,   61,   53,   45,   37,   29,   21,    
  13,   5,   60,   52,   44,   36,   28,    
  20,   12,   4,   27,   19,   11,   3   };    
  //56字节变换为48   字节(数据压缩)  
  static   unsigned   char   pc2[48]   =   {  
  13,   16,   10,   23,   0,   4,    
  2,   27,   14,   5,   20,   9,    
  22,   18,   11,   3,   25,   7,    
  15,   6,   26,   19,   12,   1,    
  40,   51,   30,   36,   46,   54,    
  29,   39,   50,   44,   32,   47,    
  43,   48,   38,   55,   33,   52,    
  45,   41,   49,   35,   28,   31   };  
  //32字节变换为48字节(数据扩展)  
  static   unsigned   char   exp[48]   =   {  
  31,   0,   1,   2,   3,   4,    
  3,   4,   5,   6,   7,   8,    
  7,   8,   9,   10,   11,   12,    
  11,   12,   13,   14,   15,   16,    
  15,   16,   17,   18,   19,   20,    
  19,   20,   21,   22,   23,   24,    
  23,   24,   25,   26,   27,   28,    
  27,   28,   29,   30,   31,   0   };  
   
  //64位数据IP(Initial   Permutation)变换表  
  static   unsigned   char   ip[64]   =   {  
  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,    
  56,   48,   40,   32,   24,   16,   8,   0,    
  58,   50,   42,   34,   26,   18,   10,   2,    
  60,   52,   44,   36,   28,   20,   12,   4,    
  62,   54,   46,   38,   30,   22,   14,   6   };  
   
  //数据逆置换(Final   Permutation)  
  static   unsigned   char   ip_1[64]   =   {  
  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,    
  32,   0,   40,   8,   48,   16,   56,   24   };  
   
  //Permutation   P  
  static   unsigned   char   pp[32]   =   {  
  15,   6,   19,   20,    
  28,   11,   27,   16,    
  0,   14,   22,   25,    
  4,   17,   30,   9,    
  1,   7,   23,   13,    
  31,   26,   2,   8,    
  18,   12,   29,   5,    
  21,   10,   3,   24   };  
   
  /*   INITIALIZE   THE   TABLES   */  
   
  /*   Table   -   s1   */  
  static   unsigned   char   s1[4][16]   =   {  
  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   };  
  /*   Table   -   s2   */  
  static   unsigned   char   s2[4][16]   =   {  
  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   };  
  /*   Table   -   s3   */  
  static   unsigned   char   s3[4][16]   =   {  
  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   };  
  /*   Table   -   s4   */  
  static   unsigned   char   s4[4][16]   =   {  
  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   };  
  /*   Table   -   s5   */  
  static   unsigned   char   s5[4][16]   =   {  
  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   };  
  /*   Table   -   s6   */  
  static   unsigned   char   s6[4][16]   =   {  
  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   };  
  /*   Table   -   s7   */  
  static   unsigned   char   s7[4][16]   =   {  
  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   };  
  /*   Table   -   s8   */  
  static   unsigned   char   s8[4][16]   =   {  
  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   };  
  /*   密钥生成中的循环左移位的累计次数*/  
  static   unsigned   char   totrot[]   =   {1,2,4,6,8,10,12,   14,   15,   17,   19,   21,   23,   25,   27,   28   };  
  /*----------------------------------------------*/  
  //long   mode   =   1;                                                                 //模式,1:加密,2:解密  
  //unsigned   char   bufferin[9],   bufferout[9];             //明文,密文  
  /*----------------------------------------------*/  
   
  long   i,   j,   k;    
  long   rotshift;                                                             //密钥移位次数    
  //long   keylen,   buflen;                                             //密钥长度,明文长度    
  unsigned   char   keybuf[65];                                       //密钥,密钥64字节缓冲区  
  unsigned   char   keyreal[57],   keys[17][49];         //实际使用56字节密钥,48字节密钥数组    
  unsigned   char   srcbuf[65],   dstbuf[65];               //明文,密文64字节缓冲区  
  unsigned   char   L[17][33],   R[17][33],   LR[65],   RL[65];         //加密时临时数据左右两部分  
  unsigned   char   E[17][49];                                         //R数组的扩展数据  
  unsigned   char   B[9][7],   BB[33],   P[33];               //E和K异或后的缓冲数组  
  unsigned   char   C[17][29],   D[17][29],   CD[57];   //56字节密钥的左右两部分  
  unsigned   char   temp1,   temp2,   m,   n,   x;  
  //1.变换密钥  
  //密钥不足8字节则用0补足(或自定义)  
  //keylen   =   strlen((const   char*)key);  
  //if(keylen<8)    
  //   memset(key+keylen,   0,   (8-keylen));    
  //将8字节密钥转换为64字节字串    
  for(i=0;i<8;i++)  
  {  
  j   =   *(key+i);  
  keybuf[8*i]   =   (j   /   128)   %   2;  
  keybuf[8*i+1]   =   (j   /   64)   %   2;  
  keybuf[8*i+2]   =   (j   /   32)   %   2;  
  keybuf[8*i+3]   =   (j   /   16)   %   2;  
  keybuf[8*i+4]   =   (j   /   8)   %   2;  
  keybuf[8*i+5]   =   (j   /   4)   %   2;  
  keybuf[8*i+6]   =   (j   /   2)   %   2;  
  keybuf[8*i+7]   =   (j   /   1)   %   2;  
  }  
   
  //根据pc1进行变换成56字节,去掉奇偶校验位  
  for(i=0;i<56;i++)  
  {  
  keyreal[i]   =   keybuf[pc1[i]];  
  }  
   
  //将56字节密钥分为左右两部分C[0],D[0]  
  for(i=0;i<28;i++)  
  {  
  C[0][i]   =   keyreal[i];  
  D[0][i]   =   keyreal[i+28];  
  }    
   
  //循环16次(i从1开始)  
   
  for(i=1;i<17;i++)  
  {  
  //根据加密或解密确定密钥顺序  
  if(mode)         //加密  
  rotshift   =   totrot[i-1];  
  else                 //解密  
  rotshift   =   totrot[16-i];  
   
  //1)左移固定位数得到C[i]和D[i];  
  for(j=0;j<28;j++)  
  {  
  C[i][j]   =   C[0][j];  
  D[i][j]   =   D[0][j];  
  }  
  for(j=0;j<rotshift;j++)  
  {  
  temp1   =   C[i][0];  
  temp2   =   D[i][0];  
  for(k=0;k<27;k++)  
  {  
  C[i][k]   =   C[i][k+1];  
  D[i][k]   =   D[i][k+1];  
  }  
  C[i][27]   =   temp1;  
  D[i][27]   =   temp2;  
  }    
   
  //2)将C[i]D[i]用pc2化简为48位k[i];  
  for(j=0;j<28;j++)  
  {  
  CD[j]   =   C[i][j];  
  CD[j+28]   =   D[i][j];  
  }  
   
  for(j=0;j<48;j++)  
  {  
  keys[i][j]   =   CD[pc2[j]];  
  }  
  }  
   
     
  问题点数:88、回复次数:8Top

1 楼xingfuniao(幸福鸟)回复于 2006-06-01 00:40:12 得分 0

 
  //2.数据处理  
  //若明文不足8字节则补0(或自定义)  
  //buflen   =   strlen((const   char*)bufferin);  
  //if(buflen<8)  
  //   memset(bufferin+buflen,   0,   (8-buflen));  
  //将8字节数据转换为64字节字串  
  for(i=0;i<8;i++)  
  {  
  j   =   *(bufferin+i);  
  srcbuf[i*8]   =   (j   /   128)   %   2;  
  srcbuf[i*8+1]   =   (j   /   64)   %   2;  
  srcbuf[i*8+2]   =   (j   /   32)   %   2;  
  srcbuf[i*8+3]   =   (j   /   16)   %   2;  
  srcbuf[i*8+4]   =   (j   /   8)   %   2;  
  srcbuf[i*8+5]   =   (j   /   4)   %   2;  
  srcbuf[i*8+6]   =   (j   /   2)   %   2;  
  srcbuf[i*8+7]   =   (j   /   1)   %   2;  
  }  
   
     
   
  //将srcbuf按ip进行变换  
   
  for(i=0;i<64;i++)  
  LR[i]   =   srcbuf[ip[i]];  
     
  //将64字节数据转换为两部分L[0],R[0]  
  for(i=0;i<32;i++)  
  {  
  L[0][i]   =   LR[i];  
  R[0][i]   =   LR[i+32];  
  }  
     
  //循环16次(i从1开始),用密钥加密数据  
  for(i=1;i<17;i++)  
  {  
  //1)将32位的R[i-1]按exp扩展为48位的E[i-1];  
  for(j=0;j<48;j++)  
  {  
  E[i-1][j]   =   R[i-1][exp[j]];  
  }  
   
  //2)异或E[i-1]和K[i];  
  for(j=0;j<48;j++)  
  {  
  keys[i][j]   =   keys[i][j]   ^   E[i-1][j];  
  }  
     
  //3)将异或结果分为8个6位长的部分B[8]  
  for(j=0;j<8;j++)  
  {  
  B[j][0]   =   keys[i][j*6];  
  B[j][1]   =   keys[i][j*6+1];  
  B[j][2]   =   keys[i][j*6+2];  
  B[j][3]   =   keys[i][j*6+3];  
  B[j][4]   =   keys[i][j*6+4];  
  B[j][5]   =   keys[i][j*6+5];  
  }  
   
  //4)循环用S表替换(j从1开始)  
  for(j=0;j<8;j++)  
  {  
  //a)B[j]第1位和第6位组合为M,作为S[j]的行号  
  m   =   2   *   B[j][0]   +   B[j][5];      
  //b)B[j]第2到5位组合为N,作为S[j]的列号  
  n   =   2   *   (2   *   (2   *   B[j][1]   +   B[j][2])   +   B[j][3])   +   B[j][4];    
  //c)用S[j][M][N]来取代B[j]  
  switch(j)  
  {  
  case   0:  
  x   =   s1[m][n];  
  break;  
  case   1:  
  x   =   s2[m][n];  
  break;  
  case   2:  
  x   =   s3[m][n];  
  break;  
  case   3:  
  x   =   s4[m][n];  
  break;  
  case   4:  
  x   =   s5[m][n];  
  break;  
  case   5:  
  x   =   s6[m][n];  
  break;  
  case   6:  
  x   =   s7[m][n];  
  break;  
  case   7:  
  x   =   s8[m][n];  
  break;  
  }  
  BB[j*4]   =   (x   /   8)   %   2;  
  BB[j*4   +   1]   =   (x   /   4)   %   2;  
  BB[j*4   +   2]   =   (x   /   2)   %   2;  
  BB[j*4   +   3]   =   (x   /   1)   %   2;  
  }  
  //5)将B[1]到B[8]按P组合得到p  
  for(j=0;j<32;j++)  
  {  
  P[j]   =   BB[pp[j]];  
  }  
   
  //6)R[i]   =   p   xor   L[i-1];L[i]   =   R[i-1];  
  for(j=0;j<32;j++)  
  {  
  R[i][j]   =   P[j]   ^   L[i-1][j];    
  L[i][j]   =   R[i-1][j];  
  }    
  }  
     
  //3.组合变换后的R[16]L[16]按ip_1变换得到最后结果  
  for(i=0;i<32;i++)  
  {  
  RL[i]   =   R[16][i];  
  RL[i+32]   =   L[16][i];  
  }  
   
  for(i=0;i<64;i++)  
  {  
  dstbuf[i]   =   RL[ip_1[i]];  
  }    
  //将64字节数据转换为8字节  
   
  for   (i   =   0;   i   <   8;   i++)    
  {  
  *(bufferout   +   i)   =   0x00;  
  for   (k   =   0;   k   <   7;   k++)  
  *(bufferout   +   i)   =   ((*(bufferout   +   i))   +   dstbuf[8*i+k])   *   2;  
  *(bufferout   +   i)   =   *(bufferout   +   i)   +   dstbuf[8*i+7];  
  }  
  return   0;  
  }  
   
   
  这个函数我怎样去使用呢,我没看懂,对DES算法不熟悉,大狭告诉我怎样使用这个函数来进行加密?  
   
  例如我现在有个密钥'57415443484441544154696d65434f53’,我想通过这个密钥对一个16进制的随机数加密如‘47972DC678443425’,想得到一个数,该怎样使用这个函数,  
   
  或者大狭要是有关于DES的完整的应用,也提供给小弟学习一下。要纯C开发的。  
   
  分不够在加!!!!!Top

2 楼happytang(一只叫苏格拉底的猪)回复于 2006-06-01 01:29:58 得分 30

网上很多DES的资料的  
  DES算法的入口参数有三个:Key、Data、Mode。其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。        
        DES算法是这样工作的:如Mode为加密,则用Key       去把数据Data进行加密,       生成Data的密码形式(64位)作为DES的输出结果;如Mode为解密,则用Key去把密码形式的数据Data解密,还原为Data的明码形式(64位)作为DES的输出结果。在通信网络的两端,双方约定一致的Key,在通信的源点用Key对核心数据进行DES加密,然后以密码形式在公共通信网(如电话网)中传输到通信网络的终点,数据到达目的地后,用同样的Key对密码数据进行解密,便再现了明码形式的核心数据。这样,便保证了核心数据(如PIN、MAC等)在公共通信网中传输的安全性和可靠性。        
   
  D.E.S   是分块加密的,将明文分割成   64   BITS   的块,   然后它们一个个接起来   。它使用56位密钥对64位的数据块进行加密,并对64bits的数据块进行16轮编码。与每轮编码时,一个48bits的“每轮”密钥值由56bits的完整密钥得出来。  
  http://topic.csdn.net/t/20050510/20/3996245.htmlTop

3 楼happytang(一只叫苏格拉底的猪)回复于 2006-06-01 01:39:35 得分 0

//long   mode   =   1;                                                                 //模式,1:加密,2:解密  
  //unsigned   char   bufferin[9],   bufferout[9];             //明文,密文  
  /*----------------------------------------------*/  
  仔细看看程序,输入输出都写得很清楚  
  不难得。还不是3des,IdesTop

4 楼jixingzhong(瞌睡虫·星辰)回复于 2006-06-01 08:50:53 得分 0

int   DES(unsigned   char   *bufferin,unsigned   char   *bufferout,   unsigned   char   *key,long   mode)  
   
  例如我现在有个密钥'57415443484441544154696d65434f53’,我想通过这个密钥对一个16进制的随机数加密如‘47972DC678443425’,想得到一个数,该怎样使用这个函数,  
  =====================================  
  密钥'57415443484441544154696d65434f53’保存在一个   unsigned   char   *中,  
            传递给这个函数的   unsigned   char   *key  
  要加密的数据如‘47972DC678443425’,传递给unsigned   char   *bufferin  
  mode   根据实际选择,传入合适的参数  
          (mode=1或其他非0数据   为加密       或者     mode   =0   为解密)  
  unsigned   char   *bufferout   为加密后数据的保存区域Top

5 楼jixingzhong(瞌睡虫·星辰)回复于 2006-06-01 08:56:32 得分 58

main()  
  {  
    unsigned   char   in[100]   =   "47972DC678443425";  
    unsigned   char   key[]   =   "57415443484441544154696d65434f53";  
    unsigned   char   out[100];  
    DES(in,   out,   key,   1);     //加密操作,数据保存于   out   中  
    puts(out);  
     
    DES(out,   in,   key,   0);     //对   out   中的数据进行还原解密操作  
    puts(in);    
  }Top

6 楼xingfuniao(幸福鸟)回复于 2006-06-01 10:34:37 得分 0

不过我想用这个密钥和数据加密后得到如下的结果,用DES得不出来,所以应该是3DES加密后得出来的  
  密钥:57415443484441544154696d65434f53  
  数据:47972DC678443425  
  加密后结果:19ECE1DC4C0BD6A6  
  上述数据为16进制数。  
   
  请大家提供3DES算法给小弟学习一下。要纯C开发的。  
   
  分不够在加!!!!!  
   
  已经新开贴,  
  http://community.csdn.net/Expert/topic/4793/4793089.xml?temp=.8899805  
   
  Top

7 楼jixingzhong(瞌睡虫·星辰)回复于 2006-06-01 10:56:00 得分 0

那楼主结了这个帖子吧   ...  
  否则两个帖子都回复很麻烦   ...Top

8 楼jixingzhong(瞌睡虫·星辰)回复于 2006-06-01 10:59:50 得分 0

先搞清除   3DES   流程就可以了   ...  
   
  其实还是一个   DES  
  只不过   反复了一下而已   ...  
  需要两个密钥,  
  似乎加密时候是   A加密,B解密,A解密   ...  
  解密的时候反一下就可以了   ~Top

相关问题

关键词

得分解答快速导航

  • 帖主:xingfuniao
  • happytang
  • jixingzhong

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo