zoukankan      html  css  js  c++  java
  • DES解码

    DES加解密算法是一个挺老的算法了,现在给出它的C语言版。

    des.h

     1 #ifdef  __cplusplus
     2 extern "C" {
     3 #endif
     4 
     5 void setKey(const char key[8]);
     6 char* des(const char datas[]);
     7 char * dedes(const char datas[]);
     8 
     9 #ifdef  __cplusplus
    10 }
    11 #endif

    des_tables.h

      1 char table_IP[]                /* 初始置换表 IP    */
      2 = {    
      3     58, 50, 42, 34, 26, 18, 10,  2,    60, 52, 44, 36, 28, 20, 12,  4,
      4     62, 54, 46, 38, 30, 22, 14,  6,    64, 56, 48, 40, 32, 24, 16,  8,
      5     57, 49, 41, 33, 25, 17,  9,  1,    59, 51, 43, 35, 27, 19, 11,  3,    
      6     61, 53, 45, 37, 29, 21, 13,  5,    63, 55, 47, 39, 31, 23, 15,  7    
      7 };
      8 
      9 const static char table_FP[]                /* 末置换表 */
     10 = {
     11     40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
     12     38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
     13     36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
     14     34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41,  9, 49, 17, 57, 25
     15 };
     16 
     17 //= {    
     18 //    40,  8, 48, 16, 56, 24, 64, 32,     39,  7, 47, 15, 55, 23, 63, 31,
     19 //    38,  6, 46, 14, 54, 22, 62, 30,        37,  5, 45, 13, 53, 21, 61, 29,
     20 //    36,  4, 44, 12, 52, 20, 60, 28,        35,  3, 43, 11, 51, 19, 59, 27,
     21 //    34,  2, 42, 10, 50, 18, 58, 26,        33,  1, 41,  9, 49, 17, 57, 25    
     22 //};
     23 
     24 char table_PC_1[]                /* 密钥置换表PC_1  */
     25 = {    
     26     57, 49, 41, 33, 25, 17,  9,     1, 58, 50, 42, 34, 26, 18,
     27     10,  2, 59, 51, 43, 35, 27,    19, 11,  3, 60, 52, 44, 36,
     28     63, 55, 47, 39, 31, 23, 15,     7, 62, 54, 46, 38, 30, 22,
     29     14,  6, 61, 53, 45, 37, 29,    21, 13,  5, 28, 20, 12,  4    
     30 };
     31 
     32 
     33 char table_PC_2[]                /* 压缩置换表 PC_2  */
     34 = {    
     35     14, 17, 11, 24,  1,  5,     3, 28, 15,  6, 21, 10,
     36     23, 19, 12,  4, 26,  8,    16,  7, 27, 20, 13,  2,
     37     41, 52, 31, 37, 47, 55,    30, 40, 51, 45, 33, 48,
     38     44, 49, 39, 56, 34, 53,    46, 42, 50, 36, 29, 32    
     39 };
     40 
     41 
     42 
     43 char table_S[8][64]              /* 48->32 bit compression tables*/
     44 = {                    /* S[1]             */
     45     14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
     46     0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
     47     4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
     48     15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
     49     /* S[2]             */
     50     15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
     51     3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
     52     0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
     53     13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
     54     /* S[3]             */
     55     10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
     56     13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
     57     13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
     58     1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
     59     /* S[4]             */
     60     7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
     61     13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
     62     10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
     63     3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
     64     /* S[5]             */
     65     2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
     66     14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
     67     4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
     68     11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
     69     /* S[6]             */
     70     12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
     71     10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
     72     9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
     73     4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
     74     /* S[7]             */
     75     4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
     76     13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
     77     1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
     78     6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
     79     /* S[8]             */
     80     13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
     81     1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
     82     7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
     83     2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11    
     84 };
     85 
     86 char table_P[]                /* P 盒置换  */
     87 = {    16,  7, 20, 21,    29, 12, 28, 17,     1, 15, 23, 26,     5, 18, 31, 10,
     88     2,  8, 24, 14,    32, 27,  3,  9,    19, 13, 30,  6,    22, 11,  4, 25    
     89 };
     90 
     91 char table_E[]
     92 = {
     93     32,  1,  2,  3,  4,  5,     4,  5,  6,  7,  8,  9,
     94     8,  9, 10, 11, 12, 13,    12, 13, 14, 15, 16, 17,
     95     16, 17, 18, 19, 20, 21,    20, 21, 22, 23, 24, 25,
     96     24, 25, 26, 27, 28, 29,    28, 29, 30, 31, 32,  1  
     97 };
     98 
     99 char table_move[] 
    100 ={
    101     1,1,2,2, 
    102     2,2,2,2, 
    103     1,2,2,2,
    104     2,2,2,1
    105 };

    des.c

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include"des_tables.h"
      4 #include"des.h"
      5 
      6 //保存这16轮的加密密钥<64位>
      7 char keys[17][8];
      8 //存着经过压缩置换后的 key
      9 char key_48[16][6];
     10 
     11 char data[16];
     12 //s盒置换结果缓冲区
     13 char data_32[4];
     14 char *data_left;
     15 char *data_right;
     16 
     17 
     18 //密钥置换
     19 void fun_InitReplacementKey(){
     20     register int i,j,l=0;
     21     register unsigned int k;
     22     register char *to_pos = keys[16];
     23     memset(to_pos,0,8);
     24     for(i=0,l=0;i<8;i++){
     25         for(j=7;j>0;j--){
     26             k = table_PC_1[l++]-1;                
     27             *to_pos = (*to_pos)| (( (*(keys[0]+(k>>3)) >>(7 - (k&0x07) ))&0x01  )<<j);                
     28         }
     29 
     30         to_pos++;
     31     }
     32 }
     33 
     34 //对密钥进行移位,并存在接下来下面的字节中
     35 void fun_MoveKey(int len , char*offset, char *dist){
     36     /////////////////////////
     37     ///错误了!!!! 是分两块进行循环移位 !!!!!!!
     38     ///< 已修改 ! 需要分左右部分 >
     39 
     40     register int i = len;
     41     unsigned char firstBit;
     42     static unsigned char *tmp;
     43     tmp =(unsigned char*)dist;
     44     memcpy(tmp,offset,8);
     45     firstBit =(unsigned char)tmp[0];
     46     firstBit = firstBit>>(8-len);
     47 
     48     //左边部分循环左移
     49     for(i=0;i< 3;i++){
     50         tmp[i] = (tmp[i]&0xfe) <<len ;        
     51         tmp[i] = tmp[i]|((tmp[i+1]>>(7-len))&0xff);
     52         tmp[i] = tmp[i]&0xfe;
     53     }
     54     
     55     tmp[i] = (tmp[i] &0xfe)<<len;
     56     tmp[i] = tmp[i]|(firstBit<<1);
     57     tmp[i] = tmp[i]&0xfe;
     58 
     59     firstBit =(unsigned char)tmp[++i];
     60     firstBit = firstBit>>(8-len);
     61 
     62     //右边部分循环左移
     63     for(i;i<7;i++){
     64         tmp[i] = (tmp[i]&0xfe) <<len ;        
     65         tmp[i] = tmp[i]|((tmp[i+1]>>(7-len))&0xff);
     66         tmp[i] = tmp[i]&0xfe;
     67     }
     68     tmp[i] = (tmp[i] &0xfe)<<len;
     69     tmp[i] = tmp[i]|(firstBit<<1);
     70     tmp[i] = tmp[i]&0xfe;
     71 
     72 }
     73 
     74 //对密钥进行压缩置换并保存到指定位置
     75 void fun_ReplacementCompressKey(char* offset,char *dist){
     76     //压缩置换是在 0-56位进行.需要先对64位密钥进行压缩为56位在进行48位选择
     77     register int i,j,k,l;
     78     register char dt;
     79     register unsigned char* tmp  = (unsigned char*)offset;
     80     char mid_tmp[7];
     81 
     82     for(i=0;i<7;i++){
     83         mid_tmp[i] = (tmp[i]<<(i)) | ((tmp[i+1])>>(7-i));
     84     }        
     85 
     86     memset(dist,0,7);
     87     //进行置换
     88     for(i=0,l=0;i<6;i++){
     89         for(dt =0,j=7;j>=0;j--){
     90             k = table_PC_2[l++]-1;        
     91             dt = dt|(( (*(mid_tmp+(k>>3)) >>(7 - k&0x07 ))&0x01  )<<j);
     92             if(j==0)
     93                 break;
     94         }
     95         dist[i] = dt;
     96     }
     97 }
     98 
     99 /**********************************************/
    100 
    101 
    102 /**********************************************/
    103 //加密过程
    104 
    105 //初始置换 ip 
    106 //从offset位置开始将数据置换到 data[8-15]字节 ,然后重新复制到data[0-7]中
    107 void fun_initReplacement(const char *offset){
    108     register int i,j,l;
    109     register unsigned char k,*tmp,*to;
    110     //将数据块区域重置为 0 
    111     tmp = (unsigned char*)offset;
    112     to = (unsigned char* )(data+8);
    113     memset(to,0,8);
    114     for(i=0,l=0;i<8;i++){
    115         for(j=7;j>=0;j--){
    116             k = table_IP[l++]-1;
    117             to[i] = to[i] | ((( *(tmp+(k>>3))>>(7- (k &0x07)))&0x01)<<j);
    118             if(j==0)
    119                 break;
    120         }
    121     }
    122     memcpy(data,data+8,8);
    123     //初始化指针
    124     data_left = data;
    125     data_right = data+4;
    126 }
    127 
    128 //末置换 fp
    129 void fun_finalReplacement(){
    130     //数据块存在 data[0]-data[7]中 !
    131     //置换临时空间 data[8]-data[15]    
    132     register int i,j,l;
    133     register unsigned char k,*tmp,*to;
    134     //将数据块区域重置为 0 
    135     tmp = (unsigned char*)data;
    136     to = (unsigned char*)(data+8);
    137     for(i=0,l=0;i<8;i++){
    138         for(j=7;j>=0;j--){
    139             k = table_FP[l++]-1;
    140             to[i] = to[i] | ((( *(tmp+(k>>3))>>(7- (k &0x07)))&0x01)<<j);
    141             if(j==0)
    142                 break;
    143         }
    144     }
    145     memcpy(data,to,8);
    146 
    147 }
    148 
    149 //扩展置换
    150 void fun_expandReplacement_32To48(){
    151     //////////将右边的数据扩展至 48 位 !
    152     register int i,j;
    153     register unsigned char k,l,*tmp,*to_pos;
    154     tmp = (unsigned char *)data_right;
    155     to_pos = (unsigned char*)(data+8);
    156     memset(to_pos,0,8);
    157     //printf("
    ---------- 扩展置换 ---------
    ");
    158     for(i=0,l=0;i<6;i++){
    159         for(j=7 ,k=0;j>=0;j--){
    160             k = table_E[l++]-1;
    161             *to_pos = (*to_pos)| (((*(tmp+(k>>3)) >>(7 - (k&0x07) ))&0x01)<<j);
    162             //printf("%d  %d  %x 
    ",l,k,((*(tmp+(k>>3)) >>(7 - (k&0x07) ))&0x01));
    163             if(j==0)
    164                 break;
    165         }
    166         to_pos++;
    167     }
    168 }
    169 
    170 //加 密钥 异或
    171 void fun_xor_48(char *ktmp){
    172     register int i;
    173     char *dtmp = data+8;
    174     for(i=0;i<6;i++){
    175         dtmp[i] = dtmp[i]^ktmp[i];
    176 
    177     }
    178 }
    179 
    180 // s盒置换
    181 void fun_S_Replacement(){
    182     // s盒工作原理 : 48位 分成8组.每组6位   0位和5位组成行定位, 1-4位组成列定位.
    183     // 定位出来的数据即为替换后的 4 位数据
    184     register unsigned char row,col,ctmp,index,i;
    185     register char *dtmp;
    186     static char tmp[4];
    187     dtmp = data+8;
    188     memset(tmp,0,4);
    189     //((*(tmp+(k>>3)) >>(7 - (k&0x07) ))&0x01)
    190     for(index =0,ctmp=0,i=0;i< 8 ;i++){
    191         // row 为:index 接下来第零位和第五位
    192         row = (((*(dtmp+((index)>>3))>>((7-((index)&0x07))))&0x01)<<1); //第0位
    193         row|=(((*(dtmp+((index+5)>>3))>>((7-((index+5)&0x07))))&0x01))&0x03;//第5位
    194 
    195         col =(((*(dtmp+((index+1)>>3))>>((7-((index+1)&0x07))))&0x01)<<3); //第1位
    196             col|= (((*(dtmp+((index+2)>>3))>>((7-((index+2)&0x07))))&0x01)<<2);    //第2位
    197             col|= (((*(dtmp+((index+3)>>3))>>((7-((index+3)&0x07))))&0x01)<<1);    //第3位
    198             col|= (((*(dtmp+((index+4)>>3))>>((7-((index+4)&0x07))))&0x01))&0x0f;//第4位
    199         ctmp = table_S[i][(row<<4)+col];
    200 
    201         //写入4位
    202         tmp[i>>1] = tmp[i>>1] | ((ctmp&0xf)<<(((~i)&0x01)<<2));
    203         index+=6;
    204     }
    205     memcpy(data+8,tmp,4);
    206 }
    207     
    208 
    209 //P盒置换
    210 void fun_P_Replacement(){
    211     register unsigned char i,k,l;
    212     static char tmp[4],j;
    213     register char *offset =data + 8;
    214     memset(tmp,0,4);
    215     for(i=0,l=0;i<4;i++){
    216         for(k=0,j=7;j>=0;j--){
    217             k = table_P[l++]-1;            
    218             tmp[i] = tmp[i] |((( * (offset+(k>>3)))>>(7 - (k&0x07))&0x01)<<j);
    219             if(j==0)
    220                 break;
    221         }
    222     }    
    223     memcpy(data+8,tmp,4);
    224 }
    225 
    226 //左右域异或
    227 void fun_xor_32(){
    228     register char i;
    229     for(i=0;i<4;i++){
    230         data_left[i] = data_left[i]^data[8+i];
    231     }
    232 }
    233 
    234 
    235 //设置 密码 <生成过程所有密码>
    236 void setKey(const char key[8]){    
    237     register int i;
    238     register char*offset,*to,*ct;
    239     memcpy(keys[0],key,8);
    240     fun_InitReplacementKey();
    241     offset =  keys[16];
    242     to = keys[0];
    243     ct = key_48[0];
    244     //16轮迭代算出需要的 <key>
    245     for(i=0;i<16;i++){
    246         fun_MoveKey(table_move[i],offset,to);
    247         fun_ReplacementCompressKey(to,ct);
    248         offset = to;
    249         ct+=6;
    250         to+=8;
    251     }
    252 }
    253 
    254 
    255 //加密
    256 char* des(const char datas[]){
    257     int i=0;
    258     static char *swapeTmp;
    259     fun_initReplacement(datas);
    260     for(i=0;i<15;i++){
    261         fun_expandReplacement_32To48();
    262         fun_xor_48(key_48[i]);
    263         fun_S_Replacement();
    264         fun_P_Replacement();
    265         fun_xor_32();
    266         swapeTmp = data_left;        
    267         data_left =data_right;
    268         data_right =swapeTmp;
    269     }//经检验前 15 轮可以正确运算...
    270     {//第16轮
    271         fun_expandReplacement_32To48();
    272         fun_xor_48(key_48[i]);
    273         fun_S_Replacement();
    274         fun_P_Replacement();
    275         fun_xor_32();
    276         //printf("
    ---- 16 轮-----
    Data: %x Left: %x Right: %x ",data,data_left,data_right);
    277         //现在状况是 data<right,left>需要将 left 和right的数据块调换过来!!!!!!
    278         memcpy(data+8,data,4);
    279         memcpy(data,data+4,4);
    280         memcpy(data+4,data+8,4);
    281         memset(data+8,0,8);
    282     }
    283     //末置换!
    284     fun_finalReplacement();
    285     return data;
    286 }
    287 
    288 //解密算法
    289 char * dedes(const char datas[]){
    290     int i=0;
    291     static char *swapeTmp;
    292     fun_initReplacement(datas);
    293     for(i=15;i>0;i--){
    294         fun_expandReplacement_32To48();
    295         fun_xor_48(key_48[i]);
    296         fun_S_Replacement();
    297         fun_P_Replacement();
    298         fun_xor_32();
    299         swapeTmp = data_left;        
    300         data_left =data_right;
    301         data_right =swapeTmp;
    302     }//经检验前 15 轮可以正确运算...
    303     {//第16轮
    304         fun_expandReplacement_32To48();
    305         fun_xor_48(key_48[i]);
    306         fun_S_Replacement();
    307         fun_P_Replacement();
    308         fun_xor_32();
    309         //现在状况是 data<right,left>需要将 left 和right的数据块调换过来!!!!!!
    310         memcpy(data+8,data,4);
    311         memcpy(data,data+4,4);
    312         memcpy(data+4,data+8,4);
    313         memset(data+8,0,8);
    314     }
    315     //末置换!
    316     fun_finalReplacement();
    317     data[8]='';
    318     return data;
    319 }
  • 相关阅读:
    第4月第1天 makefile automake
    第3月30天 UIImage imageWithContentsOfFile卡顿 Can't add self as subview MPMoviePlayerControlle rcrash
    第3月第27天 uitableviewcell复用
    learning uboot fstype command
    learning uboot part command
    linux command dialog
    linux command curl and sha256sum implement download verification package
    learning shell script prompt to run with superuser privileges (4)
    learning shell get script absolute path (3)
    learning shell args handing key=value example (2)
  • 原文地址:https://www.cnblogs.com/guoxiaoqian/p/3915400.html
Copyright © 2011-2022 走看看