[C++] DES加密算法 →→→→→进入此内容的聊天室

来自 , 2020-04-03, 写在 C++, 查看 136 次.
URL http://www.code666.cn/view/f5c3dd75
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. #define ENCRYPT 1
  6. #define DECRYPT 0
  7.  
  8. static void printHex ( char *cmd, int len );
  9. static void printArray ( const char *In, int len );
  10.  
  11. static void F_func ( bool In[32], const bool Ki[48] );    // f函数
  12. static void S_func ( bool Out[32], const bool In[48] );   // S盒代替
  13.  
  14. static void Transform ( bool *Out, bool *In, const char *Table, int len ); // 变换
  15. static void Xor ( bool *InA, const bool *InB, int len );   // 异或
  16. static void RotateL ( bool *In, int len, int loop );    // 循环左移
  17. static void ByteToBit ( bool *Out, const char *In, int bits );  // 字节组转换成位组
  18. static void BitToByte ( char *Out, const bool *In, int bits );  // 位组转换成字节组
  19.  
  20. // 16位子密钥
  21. static bool SubKey[16][48];
  22.  
  23. // 64位经过PC1转换为56位 (PC-1)
  24. const static char PC1_Table[56] =
  25. {
  26.         57, 49, 41, 33, 25, 17,  9,
  27.         1, 58, 50, 42, 34, 26, 18,
  28.         10,  2, 59, 51, 43, 35, 27,
  29.         19, 11,  3, 60, 52, 44, 36,
  30.         63, 55, 47, 39, 31, 23, 15,
  31.         7, 62, 54, 46, 38, 30, 22,
  32.         14,  6, 61, 53, 45, 37, 29,
  33.         21, 13,  5, 28, 20, 12,  4
  34. };
  35.  
  36. // 左移
  37. const static char LOOP_Table[16] =
  38. {
  39.         1, 1, 2, 2, 2, 2, 2, 2,
  40.         1, 2, 2, 2, 2, 2, 2, 1
  41. };
  42.  
  43. // 排列选择 2 (PC-2)
  44. const static char PC2_Table[48] =
  45. {
  46.         14, 17, 11, 24,   1,   5,
  47.         3,  28, 15,  6,  21,  10,
  48.         23, 19, 12,  4,  26,   8,
  49.         16,  7, 27, 20,  13,   2,
  50.         41, 52, 31, 37,  47,  55,
  51.         30, 40, 51, 45,  33,  48,
  52.         44, 49, 39, 56,  34,  53,
  53.         46, 42, 50, 36,  29,  32
  54. };
  55.  
  56. // Ri_1(32位)经过变换E后膨胀为48位 (E)  void F_func
  57. static const char E_Table[48] =
  58. {
  59.         32,   1,   2,   3,   4,   5,
  60.         4,   5,   6,   7,   8,   9,
  61.         8,   9,  10,  11,  12,  13,
  62.         12,  13,  14,  15,  16,  17,
  63.         16,  17,  18,  19,  20,  21,
  64.         20,  21,  22,  23,  24,  25,
  65.         24,  25,  26,  27,  28,  29,
  66.         28,  29,  30,  31,  32,   1
  67. };
  68.  
  69. // 8个4比特合并为32比特的排列 P
  70. const static char P_Table[32] =
  71. {
  72.         16,  7, 20, 21,
  73.         29, 12, 28, 17,
  74.         1, 15, 23, 26,
  75.         5, 18, 31, 10,
  76.         2,  8, 24, 14,
  77.         32, 27,  3,  9,
  78.         19, 13, 30,  6,
  79.         22, 11,  4, 25,
  80. };
  81.  
  82. // 经过S盒 S-boxes
  83. const static char S_Box[8][4][16] =
  84. {
  85.         {
  86.                 // S1
  87.                 {  14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7   },
  88.                 {   0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8   },
  89.                 {   4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0   },
  90.                 {  15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13   }
  91.         },
  92.         {
  93.                 // S2
  94.                 {  15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10   },
  95.                 {   3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5   },
  96.                 {   0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15   },
  97.                 {  13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9   }
  98.         },
  99.         {
  100.                 // S3
  101.                 {  10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8   },
  102.                 {  13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1   },
  103.                 {  13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7   },
  104.                 {   1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12   }
  105.         },
  106.         {
  107.                 // S4
  108.                 {   7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15   },
  109.                 {  13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9   },
  110.                 {  10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4   },
  111.                 {   3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14   }
  112.         },
  113.         {
  114.                 // S5
  115.                 {   2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9   },
  116.                 {  14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6   },
  117.                 {   4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14   },
  118.                 {  11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3   }
  119.         },
  120.         {
  121.                 // S6
  122.                 {  12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11   },
  123.                 {  10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8   },
  124.                 {   9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6   },
  125.                 {   4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13   }
  126.         },
  127.         {
  128.                 // S7
  129.                 {   4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1   },
  130.                 {  13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6   },
  131.                 {   1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2   },
  132.                 {   6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12   }
  133.         },
  134.         {
  135.                 // S8
  136.                 {  13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7   },
  137.                 {   1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2   },
  138.                 {   7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8   },
  139.                 {   2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11   }
  140.         }
  141. };
  142.  
  143. // 初始排列 (IP)
  144. const static char IP_Table[64] =
  145. {
  146.         58, 50, 42, 34, 26, 18, 10, 2,
  147.         60, 52, 44, 36, 28, 20, 12, 4,
  148.         62, 54, 46, 38, 30, 22, 14, 6,
  149.         64, 56, 48, 40, 32, 24, 16, 8,
  150.         57, 49, 41, 33, 25, 17,  9, 1,
  151.         59, 51, 43, 35, 27, 19, 11, 3,
  152.         61, 53, 45, 37, 29, 21, 13, 5,
  153.         63, 55, 47, 39, 31, 23, 15, 7
  154. };
  155.  
  156. // L16与R16合并后经过IP_1的最终排列 (IP**-1)
  157. const static char IPR_Table[64] =
  158. {
  159.         40, 8, 48, 16, 56, 24, 64, 32,
  160.         39, 7, 47, 15, 55, 23, 63, 31,
  161.         38, 6, 46, 14, 54, 22, 62, 30,
  162.         37, 5, 45, 13, 53, 21, 61, 29,
  163.         36, 4, 44, 12, 52, 20, 60, 28,
  164.         35, 3, 43, 11, 51, 19, 59, 27,
  165.         34, 2, 42, 10, 50, 18, 58, 26,
  166.         33, 1, 41,  9, 49, 17, 57, 25
  167. };
  168.  
  169. void Des_SetKey ( const char Key[8] );  //生成子密钥
  170. void Des_Run ( char Out[8], char In[8], bool Type );  //DES算法
  171.  
  172. void main ( int argc, char *argv[] )
  173. {
  174.         char key[12]={1,2,3,4,5,6,7,8};
  175.         char str[12]="Hello";
  176.         char str2[12];
  177.  
  178.         //printArray( PC2_Table, sizeof(PC2_Table)/sizeof(PC2_Table[0]) );
  179.  
  180.         printf ( "Before encrypting: " );
  181.         puts ( str );
  182.  
  183.         Des_SetKey ( key );
  184.  
  185.         memset ( str2, 0, sizeof ( str2 ) );
  186.         Des_Run ( str2, str, ENCRYPT );
  187.         printf ( "After  encrypting: " );
  188.         printHex ( str2, 8 );
  189.  
  190.         memset ( str, 0, sizeof ( str ) );
  191.         printf ( "After  decrypting: " );
  192.         Des_Run ( str, str2, DECRYPT );
  193.         puts ( str );
  194.  
  195. }
  196.  
  197. void Des_SetKey ( const char Key[8] )
  198. {
  199.         int i;
  200.         static bool K[64], *KL = &K[0], *KR = &K[28];
  201.  
  202.         ByteToBit ( K, Key, 64 );   //转换为二进制
  203.  
  204.         Transform ( K, K, PC1_Table, 56 );   //64比特的密钥K,经过PC-1后,生成56比特的串。
  205.  
  206.         //生成16个子密钥
  207.         for ( i=0; i<16; i++ )
  208.         {
  209.                 //循环左移,合并
  210.                 RotateL ( KL, 28, LOOP_Table[i] );
  211.                 RotateL ( KR, 28, LOOP_Table[i] );
  212.                 Transform ( SubKey[i], K, PC2_Table, 48 );
  213.         }
  214. }
  215.  
  216. void Des_Run ( char Out[8], char In[8], bool Type )
  217. {
  218.         int i;
  219.         static bool M[64], tmp[32], *Li = &M[0], *Ri = &M[32];
  220.  
  221.         //转换为64位的数据块
  222.         ByteToBit ( M, In, 64 );
  223.  
  224.         //IP置换 (初始)
  225.         Transform ( M, M, IP_Table, 64 );
  226.  
  227.         //该比特串被分为32位的L0和32位的R0两部分。
  228.  
  229.         if ( Type == ENCRYPT )
  230.         {
  231.                 //16轮置换
  232.                 for ( i=0; i<16; i++ )
  233.                 {
  234.                         memcpy ( tmp, Ri, 32 );
  235.  
  236.                         // R[i] = L[i-1] xor f(R[i-1], K[i])
  237.                         F_func ( Ri, SubKey[i] );
  238.  
  239.                         // 2.4.6 Exclusive-or the resulting value with L[i-1].
  240.                         // R[I]=P XOR L[I-1]
  241.                         Xor ( Ri, Li, 32 );
  242.  
  243.                         // L[i] = R[i-1]
  244.                         memcpy ( Li, tmp, 32 );
  245.  
  246.                 }
  247.         }
  248.         else
  249.         {
  250.                 // 如果解密则反转子密钥顺序
  251.                 for ( i=15; i>=0; i-- )
  252.                 {
  253.                         memcpy ( tmp, Li, 32 );
  254.                         F_func ( Li, SubKey[i] );
  255.                         Xor ( Li, Ri, 32 );
  256.                         memcpy ( Ri, tmp, 32 );
  257.                 }
  258.         }
  259.  
  260.         //R16与L16合并成64位的比特串。R16一定要排在L16前面。R16与L16合并后成的比特串,经过置换IP-1后所得的比特串就是密文。
  261.         Transform ( M, M, IPR_Table, 64 );
  262.  
  263.         BitToByte ( Out, M, 64 );
  264. }
  265.  
  266. //将32比特的输入再转化为32比特的输出
  267. void F_func ( bool In[32], const bool Ki[48] )
  268. {
  269.         static bool MR[48];
  270.  
  271.         //输入Ri-1(32比特)经过变换E后,膨胀为48比特
  272.         Transform ( MR, In, E_Table, 48 );
  273.  
  274.         //异或
  275.         Xor ( MR, Ki, 48 );
  276.  
  277.         //膨胀后的比特串分为8组,每组6比特。各组经过各自的S盒后,又变为4比特(具体过程见后),合并后又成为32比特。
  278.         S_func ( In, MR );
  279.  
  280.         //该32比特经过P变换后,输出的比特串才是32比特的f (Ri-1,Ki)。
  281.         Transform ( In, In, P_Table, 32 );
  282. }
  283.  
  284. void S_func ( bool Out[32], const bool In[48] )
  285. {
  286.         char j,m,n;
  287.  
  288.         //膨胀后的比特串分为8组,每组6比特。
  289.         for ( j=0; j<8; j++,In+=6,Out+=4 )
  290.         {
  291.                 //在其输入In[0],In[1],In[2],In[3],In[4],In[5]中,计算出m=In[0]*2+In[5], n=In[4]+In[3]*2+In[2]*4+In[1]*8,再从Sj表中查出m行,n列的值Smn。将Smn化为二进制,即得Si盒的输出。
  292.                 m = ( In[0]<<1 ) + In[5];
  293.                 n = ( In[1]<<3 ) + ( In[2]<<2 ) + ( In[3]<<1 ) + In[4];
  294.  
  295.                 ByteToBit ( Out, &S_Box[ ( int ) j][ ( int ) m][ ( int ) n], 4 );
  296.         }
  297. }
  298.  
  299. // 打印指定位置指定长度HEX值
  300. static void printHex ( char *cmd, int len )
  301. {
  302.         int i;
  303.  
  304.         for ( i=0; i<len; i++ )
  305.         {
  306.                 printf ( "[%02X]", ( unsigned char ) cmd[i] );
  307.         }
  308.         printf ( "\n" );
  309. }
  310.  
  311. // 打印数组测试用
  312. static void printArray ( const char *In, int len )
  313. {
  314.         int   i;
  315.         char tmp[256];
  316.  
  317.         memset ( tmp, 0, sizeof ( tmp ) );
  318.  
  319.         for ( i=0; i<len; i++ )
  320.         {
  321.                 tmp[ ( int ) In[i]]=In[i];
  322.         }
  323.  
  324.         for ( i=0; i<len; i++ )
  325.         {
  326.                 printf ( "[%02d]", ( unsigned char ) tmp[i] );
  327.         }
  328.         printf ( "\n" );
  329. }
  330.  
  331. void Transform ( bool *Out, bool *In, const char *Table, int len )
  332. {
  333.         int i;
  334.         static bool tmp[256];
  335.  
  336.         for ( i=0; i<len; i++ )
  337.         {
  338.                 tmp[i] = In[ Table[i]-1 ];
  339.         }
  340.         memcpy ( Out, tmp, len );
  341. }
  342.  
  343. void Xor ( bool *InA, const bool *InB, int len )
  344. {
  345.         int i;
  346.  
  347.         for ( i=0; i<len; i++ )
  348.         {
  349.                 InA[i] ^= InB[i];
  350.         }
  351. }
  352.  
  353. void RotateL ( bool *In, int len, int loop )
  354. {
  355.         static bool tmp[256];               // Sample:  loop=2
  356.         memcpy ( tmp, In, loop );           // In=12345678 tmp=12
  357.         memcpy ( In, In+loop, len-loop );   // In=345678
  358.         memcpy ( In+len-loop, tmp, loop );  // In=34567812
  359. }
  360.  
  361. // Sample:
  362. // In = [0x01]
  363. // Out = [0x01] [0x00] [0x00] [0x00] [0x00] [0x00] [0x00] [0x00]
  364. void ByteToBit ( bool *Out, const char *In, int bits )
  365. {
  366.         int i;
  367.  
  368.         for ( i=0; i<bits; i++ )
  369.         {
  370.                 // In[i]的第N位右移N位并和0x01按位"与"运算(N=1~8)
  371.                 Out[i] = ( In[i/8]>> ( i%8 ) ) & 1;
  372.         }
  373. }
  374.  
  375. void BitToByte ( char *Out, const bool *In, int bits )
  376. {
  377.         int i;
  378.  
  379.         memset ( Out, 0, ( bits+7 ) /8 );
  380.         for ( i=0; i<bits; i++ )
  381.         {
  382.                 Out[i/8] |= In[i]<< ( i%8 );
  383.         }
  384. }
  385.  
  386.  

回复 "DES加密算法"

这儿你可以回复上面这条便签

captcha