0
点赞
收藏
分享

微信扫一扫

实现PROXY穿越(4):DES算法之二


  最近忙,事比较多,活多了,还要降薪,唉。没什么时间看书,将以前的一些技术blog也移到这里。NTLM在去年年底和今年年初研究过一阵子,写了总结和 例子程序。里面涉及很多算法,在网上查了很久。(下面是以前的博客)最近想实现一个通过PROXY穿越的网络编程,将相关的内容进行一下汇总。很多东西来 自网络共产主义,也应该为共产主义有所回馈。介绍DES算法之二的实现。

 

步骤二:16次计算(16 interations)


   在步骤一中,我们获取了64bits的s,以及56bits的key。s分为2个32bit的序列,分布成为L和R,根据第一步计算,我们有了L0、R0,以及K0,进行如下的操作:

L1=R0
R1=L0 XOR F(R0,K1)


   我们得到了新的L1和R1,重复操作,直至得到L16和R16,操作公式为:

Li = R i-1
Ri = L i-1 XOR F(Ri-1,Ki)


A:Ki的获取

  在这个过程中,我们每次运算的操作需要得到新的ki进行参与。下面将介绍如何从K0依次16个获取Ki(K1-K16)。K0是一个56bits的数据,我们将其存贮56个字节的key数组中。这56个比特均分为2组,第一组0-27,第二组28-55。


   左移偏移量:


  

   1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1

   对于Ki,从左移偏移量选择对应的偏移量,例如K1=1,K4=2。将两组28位的比特分别左移指定的便宜量。例如对于K1,经过左移后,第一组为 1-27,0,第二组为29-55,28。得到一个新的56比特的数据,请保留这个新的序列,记做K1',这个数据根据下面进行序列重排:


    |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|


   经过重新排序后,我们得到48比特的数据,这个就是K1。由此我们获得了第一个参与运算的K1。


   对于Ki,将Ki-1',例如计算K2,将上次我们得到的K1',分为两组,进行相应的左移操作,得到Ki’,例如计算K2是,我们将K1’分为两组,每组左移1为,得到K2’,将Ki’进行同样排序,得到Ki。


   通过这样的操作,我们依次得到16个Ki,代码如下:


static int key_offset[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
 static int ip_key[] ={
     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};

//左移操作 
 static void getkey(IN OUT unsigned char * key,int offset){
     unsigned char temp[28];

     memcpy(temp,key + offset,28-offset);
     memcpy(temp + 28 - offset, key , offset);
     memcpy(key,temp,28);

     memcpy(temp,key + 28 + offset,28-offset);
     memcpy(temp + 28 - offset, key + 28 , offset);
     memcpy(key + 28,temp,28);
 }

 void algorithm_des(IN unsigned char * src, IN unsigned char * secrect,
                    OUT unsigned char * dst){
    ...... 
    //步骤二: 
    //获取原始的L0和R0 
     memcpy(L,s,32);
     memcpy(R,s+32,32);
    
     //进行16次计算
     for(i = 0; i < 16 ; i++){
         //获取Ki'仍然放置在key中 
         getkey(key,key_offset[i]); 
         //获取Ki,放置在K中 
         initail_permutation(key,ip_key,48,K); 
     }
 }

B:F计算


  我们已经有R0,对于每次计算Ri,都将有Ri-1,根据A的步骤,我们已经有了K1,对于每次计算,我们也有Ki。在这个步骤中,我们将实现F(Ri-1,Ki)。



step B.1:


   对于Ri-1进行序列交换,生成一个48比特的数据,排序方式如下:


  

| 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 |


   这组48比特的数据和Ki进行异或(XOR),得到一组新的48bite的数据,我们暂时记做E.



step B.2: S box的运算


  48比特的数据均分为8份,每份6比特,我们分别根据S-box的变换,每份产生4比特的数据,生成一个32bite的数据。


1、从6比特的数据中获取一个行号m和一个列号n。


  m=b0b5,n=b1b2b3b4


  例如6比特的数据为100101,则m=11(3),n=0010(2)


2、根据行号和列号,在S-box的序列中,查到相应的数值。48比特分为8组,每组查询的S-box是不一样的,分别为S1, S2, S3, S4, S5, S6, S7,S8具体如下:


S1:   0列 1列 2列 3列 4列 5列 6列 7列 8列 9列 A列 B列 C列 D列 E列 F列

0行    14  4   13  1   2   15  11  8   3   10  6   12  5   9   0   7

1行    0   15  7   4   14  2   13  1   10  6   12  11  9   5   3   8

2行    4   1   14  8   13  6   2   11  15  12  9   7   3   10  5   0

3行    15  12  8   2   4   9   1   7   5   11  3   14  10  0   6   13


S2:


    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


S3:


    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


S4


    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


S5


    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


S6


    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


S7


    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


S8


    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


  我们仍以100101为例子,假设它的第一组6比特,得到m=3,n=2,我们查询S1,在第3行,第2列中查得8,将其翻译为二进制,则转换为4比特 的数据1000,这样我们得到了新的第一组4比特,如此类推,我们得到了8组4比特的数据,按顺序组合成一个32比特的数据,暂时记为E'。



stepB.3:更换顺序

将32比特的E’根据下面进行序列更换,得到新的32位数据。


   |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|


至此我们完成了F运算。



C:获得新的Ri和Li


这步骤比较简单,如下


Li = R i-1


Ri = L i-1 XOR F(Ri-1,Ki)



D:重复16次计算,得到L16和R16


static int ip_e[] = {
     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};
 static int ip_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};

 static unsigned char s1[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 };

 static unsigned char s2[64] = {
     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 };

 static unsigned char s3[64] = {
     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 };

 static unsigned char s4[64] = {
     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 };

 static unsigned char s5[64] = {
     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 };

 static unsigned char s6[64] = {
     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 };

 static unsigned char s7[64] = {
     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 };

 static unsigned char s8[64] = {
     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 void s_box_function(IN unsigned char * data,IN unsigned char * sbox,
                            OUT unsigned char * dst){
     int m = data[0] * 2 + data[5];
     int n = data[1] * 8 + data[2] * 4 + data[3] * 2 + data[4];
     unsigned char c = sbox[m* 16 + n];
     if(c >= 8){
         dst[0] = 1;
         c = c-8;
     }else{
         dst[0] = 0;
     }
     if(c >= 4){
         dst[1] = 1;
         c = c-4;
     }else{
         dst[1] = 0;
     }
     if(c >= 2){
         dst[2] = 1;
         c = c-2;
     }else{
         dst[2] = 0;
     }
     dst[3] = c;
 }

 void algorithm_des(IN unsigned char * src, IN unsigned char * secrect,
                    OUT unsigned char * dst){
    ...... 
    //步骤二: 
    //获取原始的L0和R0 
     memcpy(L,s,32);
     memcpy(R,s+32,32);
    
     //进行16次计算
     for(i = 0; i < 16 ; i++){
         //获取Ki 
         getkey(key,key_offset[i]);
         initail_permutation(key,ip_key,48,K);

         //F计算 
         initail_permutation(R,ip_e,48,E);
         xorbit(E,K,48,E);
         s_box_function(E,s1,E);
         s_box_function(E + 6,s2,E + 4);
         s_box_function(E + 12,s3,E + 8);
         s_box_function(E + 18,s4,E + 12);
         s_box_function(E + 24,s5,E + 16);
         s_box_function(E + 30,s6,E + 20);
         s_box_function(E + 36,s7,E + 24);
         s_box_function(E + 42,s8,E + 28);
         initail_permutation(E,ip_p,32,E);

        //更换序列 
         xorbit(E,L,32,E);
         memcpy(L,R,32);
         memcpy(R,E,32);
     }
 }


举报

相关推荐

0 条评论