Chinaunix首页 | 论坛 | 博客
  • 博客访问: 515244
  • 博文数量: 87
  • 博客积分: 4086
  • 博客等级: 上校
  • 技术积分: 900
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-23 15:55
文章分类

全部博文(87)

文章存档

2012年(3)

2010年(13)

2009年(7)

2008年(64)

我的朋友

分类: C/C++

2012-04-09 16:38:45

从现象上来讲,DES加密算法是对8个字节明文加密,加密时需要一个8个字节的密钥,加密后生成一个8个字节的密文;解密过程也需要8个字节的密钥,将八个字节的密文解密成明文。具体的实现过程可以在网上搜索一篇名为《DES算法原理及实现》的论文,这里只给出算法的代码供参考。

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <string.h>

  3. typedef unsigned char     uint8_t;
  4. typedef unsigned short    uint16_t;
  5. typedef unsigned int    uint32_t;
  6. typedef char            int8_t;
  7. typedef short            int16_t;
  8. typedef int                int32_t;

  9. const uint8_t DATA_IP_Table[64] =
  10. {
  11.     57,49,41,33,25,17,9,1,
  12.     59,51,43,35,27,19,11,3,
  13.     61,53,45,37,29,21,13,5,
  14.     63,55,47,39,31,23,15,7,
  15.     56,48,40,32,24,16,8,0,
  16.     58,50,42,34,26,18,10,2,
  17.     60,52,44,36,28,20,12,4,
  18.     62,54,46,38,30,22,14,6
  19. };

  20. const uint8_t DATA_IP_1_Table[64] =
  21. {
  22.     39,7,47,15,55,23,63,31,
  23.     38,6,46,14,54,22,62,30,
  24.     37,5,45,13,53,21,61,29,
  25.     36,4,44,12,52,20,60,28,
  26.     35,3,43,11,51,19,59,27,
  27.     34,2,42,10,50,18,58,26,
  28.     33,1,41,9,49,17,57,25,
  29.     32,0,40,8,48,16,56,24
  30. };

  31. const uint8_t DATA_E_Table[48] =
  32. {
  33.     31, 0, 1, 2, 3, 4,
  34.     3, 4, 5, 6, 7, 8,
  35.     7, 8,9,10,11,12,
  36.     11,12,13,14,15,16,
  37.     15,16,17,18,19,20,
  38.     19,20,21,22,23,24,
  39.     23,24,25,26,27,28,
  40.     27,28,29,30,31, 0
  41. };

  42. const uint8_t DATA_P_Table[32] =
  43. {
  44.     15,6,19,20,28,11,27,16,
  45.     0,14,22,25,4,17,30,9,
  46.     1,7,23,13,31,26,2,8,
  47.     18,12,29,5,21,10,3,24
  48. };

  49. const uint8_t DATA_S_Table[8][4][16] =
  50. {
  51.     /* S1 */
  52.     {
  53.         {14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},
  54.         {0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},
  55.         {4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},
  56.         {15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}
  57.     },
  58.     /* S2 */
  59.     {
  60.         {15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10},
  61.         {3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},
  62.         {0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},
  63.         {13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}
  64.     },
  65.     /* S3 */
  66.     {
  67.         {10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},
  68.         {13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},
  69.         {13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},
  70.         {1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}
  71.     },
  72.     /* S4 */
  73.     {
  74.         {7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15},
  75.         {13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},
  76.         {10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},
  77.         {3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}
  78.     },
  79.     /* S5 */
  80.     {
  81.         {2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},
  82.         {14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6},
  83.         {4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14},
  84.         {11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}
  85.     },
  86.     /* S6 */
  87.     {
  88.         {12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11},
  89.         {10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8},
  90.         {9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6},
  91.         {4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}
  92.     },
  93.     /* S7 */
  94.     {
  95.         {4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1},
  96.         {13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6},
  97.         {1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2},
  98.         {6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}
  99.     },
  100.     /* S8 */
  101.     {
  102.         {13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7},
  103.         {1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2},
  104.         {7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},
  105.         {2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}
  106.     }
  107. };

  108. const uint8_t KEY_PC_1[56] =
  109. {    
  110.     56,48,40,32,24,16,8,
  111.     0,57,49,41,33,25,17,
  112.     9,1,58,50,42,34,26,
  113.     18,10,2,59,51,43,35,
  114.     62,54,46,38,30,22,14,
  115.     6,61,53,45,37,29,21,
  116.     13,5,60,52,44,36,28,
  117.     20,12,4,27,19,11,3
  118. };

  119. const uint8_t KEY_PC_2[48] =
  120. {
  121.     13,16,10,23,0,4,2,27,
  122.     14,5,20,9,22,18,11,3,
  123.     25,7,15,6,26,19,12,1,
  124.     40,51,30,36,46,54,29,39,
  125.     50,44,32,46,43,48,38,55,
  126.     33,52,45,41,49,35,28,31
  127. };

  128. const uint8_t KEY_Shift[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

  129. /************************************************************
  130.  * 8 bytes to 64 bits                                        *
  131.  ***********************************************************/
  132. static void Bytes8ToBits64(uint8_t res[8], uint8_t *dst)
  133. {
  134.     int32_t i, j;
  135.     uint8_t temp;

  136.     for (i = 0; i < 8; i++)
  137.     {
  138.         temp = res[i];
  139.         for (j = 0; j < 8; j++)
  140.         {
  141.             *dst = temp & 0x01;
  142.             temp >>= 1;
  143.             dst++;
  144.         }
  145.     }
  146. }

  147. /************************************************************
  148.  * 64 bits to 8 bytes                                        *
  149.  ***********************************************************/
  150. static void Bits64ToBytes8(uint8_t dst[8], uint8_t *src)
  151. {
  152.     int32_t i, j;
  153.     uint8_t temp;

  154.     for (i = 0; i < 8; i++)
  155.     {
  156.         temp = 0;
  157.         for (j = 0; j < 8; j++)
  158.         {
  159.             temp >>= 1;
  160.             if ((*src) & 0x01)
  161.             {
  162.                 temp |= 0x80;
  163.             }

  164.             src++;
  165.         }

  166.         dst[i] = temp;
  167.     }
  168. }

  169. /************************************************************
  170.  * IP transfer                                                *
  171.  ***********************************************************/
  172. void DES_IP_Transfer(uint8_t data[64])
  173. {
  174.     uint8_t temp[64];
  175.     int32_t i;

  176.     for (i = 0; i < 64; i++)
  177.     {
  178.         temp[i] = data[DATA_IP_Table[i]];
  179.     }

  180.     memcpy(data, temp, 64);
  181. }

  182. /************************************************************
  183.  * IP-1 transfer                                            *
  184.  ***********************************************************/
  185. void DES_IP_1_Transfer(uint8_t data[64])
  186. {
  187.     uint8_t temp[64];
  188.     int32_t i;

  189.     for (i = 0; i < 64; i++)
  190.     {
  191.         temp[i] = data[DATA_IP_1_Table[i]];
  192.     }

  193.     memcpy(data, temp, 64);
  194. }

  195. /************************************************************
  196.  * P transfer                                                *
  197.  ***********************************************************/
  198. void DES_P_Transfer(uint8_t data[32])
  199. {
  200.     int32_t i;
  201.     uint8_t temp[32];

  202.     for (i = 0; i < 32; i++)
  203.     {
  204.         temp[i] = data[DATA_P_Table[i]];
  205.     }

  206.     memcpy(data, temp, 32);
  207. }

  208. /************************************************************
  209.  * KEY PC-1 transfer                                        *
  210.  ***********************************************************/
  211. void DES_PC1_Transfer(uint8_t key[64], uint8_t pc1[56])
  212. {
  213.     int32_t i;

  214.     for (i = 0; i < 56; i++)
  215.     {
  216.         *(pc1+i) = key[KEY_PC_1[i]];
  217.     }
  218. }

  219. /************************************************************
  220.  * KEY PC-2 transfer                                        *
  221.  ***********************************************************/
  222. void DES_PC2_Transfer(uint8_t pc1[56], uint8_t pc2[48])
  223. {
  224.     int32_t i;

  225.     for (i = 0; i < 48; i++)
  226.     {
  227.         *(pc2+i) = pc1[KEY_PC_2[i]];
  228.     }
  229. }

  230. /************************************************************
  231.  * subkeys shift left                                        *
  232.  ***********************************************************/
  233. void DES_Shift(uint8_t subkey[56], uint8_t time)
  234. {
  235.     uint8_t temp[56];

  236.     memcpy(temp, (subkey+time), 28-time);
  237.     memcpy((temp+28-time), subkey, time);
  238.     memcpy((temp+28), (subkey+time+28), 28-time);
  239.     memcpy((temp+56-time), (subkey+28), time);

  240.     memcpy(subkey, temp, 56);
  241. }

  242. /************************************************************
  243.  * make sub keys                                            *
  244.  ***********************************************************/
  245. void DES_MakeSubKeys(uint8_t key[64], uint8_t subkeys[16][48])
  246. {
  247.     uint8_t temp[56];
  248.     int32_t i;

  249.     DES_PC1_Transfer(key, temp);
  250.     for (i = 0; i < 16; i++)
  251.     {
  252.         DES_Shift(temp, KEY_Shift[i]);
  253.         DES_PC2_Transfer(temp, subkeys[i]);
  254.     }
  255. }    

  256. /************************************************************
  257.  * data expand                                                *
  258.  ***********************************************************/
  259. void DES_DataExpand(uint8_t data[48])
  260. {
  261.     uint8_t temp[48];
  262.     int32_t i;

  263.     for (i = 0; i < 48; i++)
  264.     {
  265.         temp[i] = data[DATA_E_Table[i]];
  266.     }

  267.     memcpy(data, temp, 48);
  268. }

  269. /************************************************************
  270.  * S-Box                                                     *
  271.  ***********************************************************/
  272. void DES_SBox(uint8_t data[48])
  273. {
  274.     int32_t i;
  275.     uint8_t row, col;
  276.     uint8_t in_p, out_p;
  277.     uint8_t out;

  278.     in_p = 0;
  279.     out_p = 0;
  280.     for (i = 0; i < 8; i++)
  281.     {
  282.         row = (data[in_p] << 1) + data[in_p+5];
  283.         col = (data[in_p+1] << 3) | (data[in_p+2] << 2) | (data[in_p+3] << 1) + data[in_p+4];

  284.         out = DATA_S_Table[i][row][col];
  285.         in_p += 6;

  286.         data[out_p++] = (out >> 3) & 0x01;
  287.         data[out_p++] = (out >> 2) & 0x01;
  288.         data[out_p++] = (out >> 1) & 0x01;
  289.         data[out_p++] = out & 0x01;
  290.     }
  291. }    

  292. /************************************************************
  293.  * DES XOR                                                     *
  294.  ***********************************************************/
  295. void DES_XOR(uint8_t *dst, uint8_t *src, int count)
  296. {
  297.     while (count--)
  298.     {
  299.         *dst ^= *src;
  300.         dst++;
  301.         src++;
  302.     }
  303. }

  304. /************************************************************
  305.  * Swap L&R                                                     *
  306.  ***********************************************************/
  307. void DES_Swap(uint8_t *left, uint8_t *right)
  308. {
  309.     uint8_t temp[32];

  310.     memcpy(temp, left, 32);
  311.     memcpy(left, right, 32);
  312.     memcpy(right, temp, 32);
  313. }

  314. /************************************************************
  315.  * Encrypt Block                                             *
  316.  ***********************************************************/
  317. void DES_EncryptBlock(uint8_t plain_data[8], uint8_t sub_keys[16][48], uint8_t cipher_data[8])
  318. {
  319.     uint8_t plain_bits[64];
  320.     uint8_t temp[48];
  321.     uint8_t i;

  322.     Bytes8ToBits64(plain_data, plain_bits);

  323.     DES_IP_Transfer(plain_bits);
  324.     for (i = 0; i < 16; i++)
  325.     {
  326.         memcpy(temp, (plain_bits+32), 32);
  327.         DES_DataExpand(temp);
  328.         DES_XOR(temp, sub_keys[i], 48);
  329.         DES_SBox(temp);
  330.         DES_P_Transfer(temp);
  331.         DES_XOR(plain_bits, temp, 32);
  332.         if (i != 15)
  333.         {
  334.             DES_Swap(plain_bits, plain_bits+32);
  335.         }
  336.     }

  337.     DES_IP_1_Transfer(plain_bits);
  338.     Bits64ToBytes8(cipher_data, plain_bits);
  339. }

  340. /************************************************************
  341.  * Dencrypt Block                                             *
  342.  ***********************************************************/
  343. void DES_DencryptBlock(uint8_t cipher_data[8], uint8_t sub_keys[16][48], uint8_t plain_data[8])
  344. {
  345.     uint8_t cipher_bits[64];
  346.     uint8_t temp[48];
  347.     int8_t i;

  348.     Bytes8ToBits64(cipher_data, cipher_bits);

  349.     DES_IP_Transfer(cipher_bits);
  350.     for (i = 15; i >= 0; i--)
  351.     {
  352.         memcpy(temp, (cipher_bits+32), 32);
  353.         DES_DataExpand(temp);
  354.         DES_XOR(temp, sub_keys[i], 48);
  355.         DES_SBox(temp);
  356.         DES_P_Transfer(temp);
  357.         DES_XOR(cipher_bits, temp, 32);
  358.         if (i != 0)
  359.         {
  360.             DES_Swap(cipher_bits, cipher_bits+32);
  361.         }
  362.     }

  363.     DES_IP_1_Transfer(cipher_bits);
  364.     Bits64ToBytes8(plain_data, cipher_bits);
  365. }

  366. int main(int argc, char **argv)
  367. {
  368.     uint8_t data[8] = { 0x01, 0x02, 0x07, 0x04, 0x05, 0x06, 0x07, 0x08 }; // data tobe encrypted
  369.     uint8_t key[8] = { 0x30, 0x30, 0x32, 0x30, 0x30, 0x37, 0x30, 0x30 }; // key for encrypt
  370.     uint8_t cipher_data[8];
  371.     uint8_t key_bits[64];
  372.     uint8_t sub_keys[16][48];
  373.     uint8_t i;

  374.     Bytes8ToBits64(key, key_bits);
  375.     DES_MakeSubKeys(key_bits, sub_keys);
  376.     DES_EncryptBlock(data, sub_keys, cipher_data);

  377.     printf("cipher data is : ");
  378.     for (i = 0; i < 8; i++)
  379.     {
  380.         printf("%02x ", cipher_data[i]);
  381.     }
  382.     printf("\n");
  383.     
  384.     DES_DencryptBlock(cipher_data, sub_keys, data);
  385.     printf(" plain data is : ");
  386.     for (i = 0; i < 8; i++)
  387.     {
  388.         printf("%02x ", data[i]);
  389.     }

  390.     printf("\n");


  391.     return 0;
  392. }

阅读(3082) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~