zoukankan      html  css  js  c++  java
  • DES算法的C语言实现

    利用C语言实现DES算法,分组密码原理过程很简单,但是在写的过程中检查了好久才发现错误原因,主要有两点:

    1.在加密过程16轮迭代过程中,最后一轮迭代运算后的结果并没有进行交换,即C=IP-1(R16,L16),这样做的目的是为了加密解密使用同一个算法

    2.在S盒的过程中,移位后应该加括号,否则+的优先级高于<<,会出错,下面是算法源码:

      1 #include "des.h"
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 
      5 const unsigned char IP_table[64] = {
      6 58, 50, 42, 34, 26, 18, 10, 2,
      7 60, 52, 44, 36, 28, 20, 12, 4,
      8 62, 54, 46, 38, 30, 22, 14, 6,
      9 64, 56, 48, 40, 32, 24, 16, 8,
     10 57, 49, 41, 33, 25, 17, 9, 1,
     11 59, 51, 43, 35, 27, 19, 11, 3,
     12 61, 53, 45, 37, 29, 21, 13, 5,
     13 63, 55, 47, 39, 31, 23, 15, 7
     14 };
     15 
     16 const unsigned char IPR_table[64] = {
     17 40, 8, 48, 16, 56, 24, 64, 32,
     18 39, 7, 47, 15, 55, 23, 63, 31,
     19 38, 6, 46, 14, 54, 22, 62, 30,
     20 37, 5, 45, 13, 53, 21, 61, 29,
     21 36, 4, 44, 12, 52, 20, 60, 28,
     22 35, 3, 43, 11, 51, 19, 59, 27,
     23 34, 2, 42, 10, 50, 18, 58, 26,
     24 33, 1, 41, 9, 49, 17, 57, 25
     25 };
     26 
     27 const unsigned char E_table[48] = {
     28 32, 1, 2, 3, 4, 5,
     29 4, 5, 6, 7, 8, 9,
     30 8, 9, 10, 11, 12, 13,
     31 12, 13, 14, 15, 16, 17,
     32 16, 17, 18, 19, 20, 21,
     33 20, 21, 22, 23, 24, 25,
     34 24, 25, 26, 27, 28, 29,
     35 28, 29, 30, 31, 32, 1
     36 };
     37 
     38 const unsigned char P_table[32] = {
     39 16, 7, 20, 21, 29, 12, 28, 17,
     40 1, 15, 23, 26, 5, 18, 31, 10,
     41 2, 8, 24, 14, 32, 27, 3, 9,
     42 19, 13, 30, 6, 22, 11, 4, 25
     43 };
     44 
     45 const unsigned char PC1_table[56] = {
     46 57, 49, 41, 33, 25, 17, 9,
     47 1, 58, 50, 42, 34, 26, 18,
     48 10, 2, 59, 51, 43, 35, 27,
     49 19, 11, 3, 60, 52, 44, 36,
     50 63, 55, 47, 39, 31, 23, 15,
     51 7, 62, 54, 46, 38, 30, 22,
     52 14, 6, 61, 53, 45, 37, 29,
     53 21, 13, 5, 28, 20, 12, 4
     54 };
     55 
     56 const unsigned char LOOP_table[16] = {
     57 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
     58 };
     59 
     60 const unsigned char PC2_table[48] = {
     61 14, 17, 11, 24, 1, 5,
     62 3, 28, 15, 6, 21, 10,
     63 23, 19, 12, 4, 26, 8,
     64 16, 7, 27, 20, 13, 2,
     65 41, 52, 31, 37, 47, 55,
     66 30, 40, 51, 45, 33, 48,
     67 44, 49, 39, 56, 34, 53,
     68 46, 42, 50, 36, 29, 32
     69 };
     70 
     71 const unsigned char sbox[8][4][16] = {
     72 // S1 
     73 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
     74 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
     75 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
     76 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
     77 //S2
     78 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
     79 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
     80 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
     81 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
     82 //S3
     83 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
     84 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
     85 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
     86 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
     87 //S4
     88 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
     89 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
     90 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
     91 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
     92 //S5
     93 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
     94 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
     95 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
     96 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
     97 //S6
     98 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
     99 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
    100 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
    101 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
    102 //S7
    103 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
    104 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
    105 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
    106 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
    107 //S8
    108 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
    109 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
    110 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
    111 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
    112 };
    113 
    114 void ByteToBit(unsigned char* out, const unsigned char* in, const int bits){
    115 for(int i=0;i<bits;i++)
    116 out[i]=(in[i/8]>>(7-i%8))&1;
    117 }
    118 
    119 void BitToByte(unsigned char* out, const unsigned char* in, const int bits){
    120 memset(out, 0, (bits + 7) / 8);
    121 for(int i=0;i<bits;i++)
    122 out[i/8]|=in[i]<<(7-i%8);
    123 }
    124 
    125 void Transform(unsigned char* out,const unsigned char* in, const unsigned char* table, const int len){
    126 unsigned char tmp[64] = {0};
    127 for (int i = 0; i < len; i++)
    128 tmp[i] = in[table[i] - 1];
    129 memcpy(out, tmp, len);
    130 }
    131 
    132 void RotateL(unsigned char* in, const int len, int loop){
    133 static unsigned char tmp[64];
    134 memcpy(tmp, in, len);
    135 memcpy(in, in + loop, len - loop);
    136 memcpy(in + len - loop, tmp, loop);
    137 }
    138 
    139 static unsigned char subKey[16][48] = { 0 };
    140 void setKey(const unsigned char* in){
    141 char key[64] = { 0 };
    142 ByteToBit(key, in, 64);
    143 char temp[56]={0};
    144 Transform(temp, key, PC1_table, 56);
    145 for(int i=0;i<16;i++){
    146 RotateL(temp, 28, LOOP_table[i]);
    147 RotateL(temp + 28, 28, LOOP_table[i]);
    148 Transform(subKey[i], temp, PC2_table, 48);
    149 }
    150 }
    151 
    152 void xor(unsigned char* in1,const unsigned char* in2,int len){
    153 for(int i=0;i<len;i++)
    154 in1[i]^=in2[i];
    155 }
    156 
    157 void sbox_exchange(unsigned char* out,const unsigned char* in){
    158 char row, column;
    159 for (int i = 0; i < 8; i++){
    160 char num = 0;
    161 row = (in[6 * i]<<1)+ in[6 * i + 5];
    162 column = (in[6 * i + 1] << 3) + (in[6 * i + 2] << 2) + (in[6 * i + 3] << 1) + in[6 * i + 4];
    163 num = sbox[i][row][column];
    164 for (int j = 0; j < 4; j++)
    165 {
    166 out[4 * i + j] = (num >> (3 - j)) & 1;
    167 }
    168 }
    169 }
    170 
    171 void F_func(unsigned char* out,const unsigned char* in,unsigned char* subKey){
    172 unsigned char temp[48]={0};
    173 unsigned char res[32]={0};
    174 Transform(temp, in, E_table, 48);
    175 xor(temp,subKey,48);
    176 sbox_exchange(res,temp);
    177 Transform(out, res, P_table, 32);
    178 }
    179 
    180 void encryptDES(unsigned char* out,const unsigned char* in, const unsigned char* key){
    181     unsigned char input[64] = { 0 };
    182     unsigned char output[64] = { 0 };
    183     unsigned char tmp[64] = { 0 };
    184     ByteToBit(input, in, 64);
    185     Transform(tmp, input, IP_table, 64);
    186     char* Li = &tmp[0], *Ri = &tmp[32];
    187     setKey(key);
    188     for(int i=0;i<16;i++){
    189         char temp[32]={0};
    190         memcpy(temp,Ri,32);
    191         F_func(Ri, Ri,subKey[i]);
    192         xor(Ri, Li, 32);
    193         memcpy(Li,temp,32);
    194     }
    195     RotateL(tmp, 64, 32);//the input is LR,output is RL
    196     Transform(output, tmp, IPR_table, 64);
    197     BitToByte(out, output,64);
    198 }
    199 
    200 void decryptDES(unsigned char* out,const unsigned char* in, const unsigned char* key){
    201     unsigned char input[64] = { 0 };
    202     unsigned char output[64] = { 0 };
    203     unsigned char tmp[64] = { 0 };
    204     ByteToBit(input, in, 64);
    205     Transform(tmp, input, IP_table, 64);
    206     char* Li = &tmp[0], *Ri = &tmp[32];
    207     setKey(key);
    208     RotateL(tmp, 64, 32);
    209     for (int i = 0; i < 16; i++){
    210         char temp[32] = { 0 };
    211         memcpy(temp, Li, 32);
    212         F_func(Li, Li,subKey[15 - i]);
    213         xor(Li, Ri, 32);
    214         memcpy(Ri, temp, 32);
    215     }
    216     Transform(output, tmp, IPR_table, 64);
    217     BitToByte(out, output, 64);
    218 }
  • 相关阅读:
    DevExpress.XtraReports报表,动态设置报表布局
    使datagridview的cell只能输入整数的方法
    关于昨天我那个问题:“DEV的DATAVIEW,能不能自己动计算并显示行中某个单元格值是其它单元格值相乘后得来的??”
    给dataGridView 添加合计行的实现方法
    实现textBox只能输入数字的一种方法!
    C#2005如何读取XML文件中的数据库连接字符串??? (好像和2003不一样啊) 急,跪求!
    请教各位在C#中这样的数据显示方式是用Datagrid控件生成的吗??(行和列数固定,能够显示行标头)
    C#2005用XML来保存连接数据库的字符串(这样改变了服务器连接配制只需改一下这个文件就成了),琢磨了几天终于有解了,和大家分享一下,希望高手指点!
    请教方法和例子:VS2003的datagrid控件,如何实现用鼠标拖动的方法选中任意区域的多个单元格,然后进行统一编辑??
    C#2005如何读取XML文件中的数据库连接字符串??? (好像和2003不一样啊) 急,跪求!
  • 原文地址:https://www.cnblogs.com/hhhhan1025/p/10078985.html
Copyright © 2011-2022 走看看