DES加密的C语言实现

  数据加密标准DES加密算法是一种对称加密算法,DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小。这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。使用子密钥对其中一半应用循环功能,然后将输出与另一半进行“异或”运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。DES 使用 16 个循环,使用异或,置换,代换,移位操作四种基本运算。

 下面是我自己用C语言实现的DES加密代码,如有错误,欢迎指正!

  1 #include
  2 #include
  3 #include<string.h>
  4 
  5 //IP初始置换表
  6 int IP_Table[64]={             
  7     58,50,42,34,26,18,10, 2,60,52,44,36,28,20,12, 4,
  8     62,54,46,38,30,22,14, 6,64,56,48,40,32,24,16, 8,
  9     57,49,41,33,25,17, 9, 1,59,51,43,35,27,19,11, 3,
 10     61,53,45,37,29,21,13, 5,63,55,47,39,31,23,15, 7 
 11 };
 12 
 13 //IP逆置换表
 14 int IPR_Table[64] = {
 15         40,8,48,16,56,24,64,32,39,7,47,15,55,23,63,31,
 16         38,6,46,14,54,22,62,30,37,5,45,13,53,21,61,29,
 17         36,4,44,12,52,20,60,28,35,3,43,11,51,19,59,27,
 18         34,2,42,10,50,18,58,26,33,1,41,9,49,17,57,25
 19 };
 20 
 21 //E位选择表(扩展置换表)
 22 int E_Table[48] = {
 23         32,1,2,3,4,5,4,5,6,7,8,9,
 24         8,9,10,11,12,13,12,13,14,15,16,17,
 25         16,17,18,19,20,21,20,21,22,23,24,25,
 26         24,25,26,27,28,29,28,29,30,31,32,1
 27 };
 28 int P_Table[32] = {
 29         16,7,20,21,29,12,28,17,1,15,23,26,5,18,31,10,
 30         2,8,24,14,32,27,3,9,19,13,30,6,22,11,4,25
 31 };
 32 
 33 int PC1_Table[56] = {
 34         57,49,41,33,25,17,9,1,58,50,42,34,26,18,
 35         10,2,59,51,43,35,27,19,11,3,60,52,44,36,
 36         63,55,47,39,31,23,15,7,62,54,46,38,30,22,
 37         14,6,61,53,45,37,29,21,13,5,28,20,12,4
 38 };
 39 //PC2选位表(密钥生成置换表2)
 40 int PC2_Table[48] = {
 41         14,17,11,24,1,5,3,28,15,6,21,10,
 42         23,19,12,4,26,8,16,7,27,20,13,2,
 43         41,52,31,37,47,55,30,40,51,45,33,48,
 44         44,49,39,56,34,53,46,42,50,36,29,32
 45 };
 46 //左移位数表 
 47  int LOOP_Table[16] = {
 48     1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
 49 };
 50 // S盒
 51  int S_Box[8][4][16] = {
 52         // S1 
 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         //S2
 58         15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,
 59         3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,
 60         0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,
 61         13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9,
 62         //S3
 63         10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,
 64         13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,
 65         13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,
 66         1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12,
 67         //S4
 68         7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,
 69         13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,
 70         10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,
 71         3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14,
 72         //S5
 73         2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,
 74         14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,
 75         4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,
 76         11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3,
 77         //S6
 78         12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,
 79         10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,
 80         9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,
 81         4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13,
 82         //S7
 83         4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,
 84         13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,
 85         1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,
 86         6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12,
 87         //S8
 88         13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,
 89         1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,
 90         7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,
 91         2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11
 92 };
 93 void ShowArray(int *array,int num);
 94 void BitsCopy(int *DatOut,int *DatIn,int Len);
 95 //将字符数组转换成二进制数组
 96 void CharToBit(char *input,int *output,int bits)
 97 {
 98     int i=0;
 99     for(i=0;i)
100     {
101         output[i]=(input[i/8]>>(i%8))&1; 
102     }
103 }
104 
105 //将二进制数组转换成字符数组
106 void BitToChar(int *input, char *output, int bits)
107 {
108     int i=0;
109     for(i=0;i<(bits/8);i++)
110     {
111         output[i]=0;
112     }
113     for(i=0;i)
114     {
115         output[i/8]|=input[i]<<(i%8);    
116     }
117 }
118 //完成异或操作
119 void  Xor(int InA[],int InB[],int len)
120 {
121     int i=0;
122     for(i=0;i)
123     {
124         InA[i]=InA[i]^InB[i];                  //按位异或 
125     }
126 }
127 
128 //IP初始置换和逆置换函数,由table决定是逆置换还是初始置换
129 void IP_IPR(int input[64],int output[64],int table[64])
130 {
131     int i=0;
132     for(i=0;i<64;i++)
133     {
134         output[i]=input[table[i]-1];
135     }
136 }
137 //E盒扩展
138 void E(int input[32],int output[48],int table[48])
139 {
140     int i=0;
141     for(i=0;i<48;i++)
142     {
143         output[i]=input[table[i]-1];
144     }
145 }
146 
147 //P盒替代
148 void P(int input[32],int output[32],int table[32])
149 {
150     
151     int i=0;
152     for(i=0;i<32;i++)
153     {
154         output[i]=input[table[i]-1];
155     }
156 }
157 
158 //PC-1置换选择
159 void PC_1(int input[64],int output[56],int table[56])
160 {
161     int i=0;
162     for(i=0;i<56;i++)
163     {
164         output[i]=input[table[i]-1];
165     }
166 }
167 
168 //PC-2置换选择
169 void PC_2(int input[56],int output[48],int table[48])
170 {
171     int i=0;
172     for(i=0;i<48;i++)
173     {
174         output[i]=input[table[i]-1];
175     }
176 }
177 
178 //S盒压缩
179 void S(int input[48],int output[32],int table[8][4][16])
180 {
181     int i,X,Y;                                    // i为8个S盒 
182     for(i=0,Y=0,X=0;i<8;i++,input+=6,output+=4)   // 每执行一次,输入数据偏移6位 
183     {                                              // 每执行一次,输出数据偏移4位
184         Y=(input[0]<<1)+input[5];                          // af代表第几行
185         X=(input[1]<<3)+(input[2]<<2)+(input[3]<<1)+input[4]; // bcde代表第几列
186         char temp=(char)table[i][4][16];
187         CharToBit(&temp,output,4);      // 把找到的点数据换为二进制    
188     }
189 }
190 //F轮函数
191 void F_func(int input[32],int subkey[48])
192 {
193     int MiR[48]={0};
194     int temp[32];
195     E(input,MiR,E_Table);                // 输入32位通过E选位变为48位
196     printf("E盒扩展:\n");
197     ShowArray(MiR,48);
198     Xor(MiR,subkey,48);                   // 和子密钥异或
199     S(MiR,input,S_Box);                 // S盒变换
200     printf("S盒替代:\n");
201     ShowArray(input,32);
202     BitsCopy(temp,input,32);
203     P(temp,input,P_Table);  // P置换后输出
204     printf("P盒置换:\n");
205     ShowArray(input,32);
206 }
207 /*-------------------------------
208  把DatIn开始的长度位Len位的二进制
209  复制到DatOut后
210 --------------------------------*/
211 void BitsCopy(int *DatOut,int *DatIn,int Len)     // 数组复制 OK 
212 {
213     int i=0;
214     for(i=0;i)
215     {
216         DatOut[i]=DatIn[i];
217     }
218 }
219 
220 //子秘钥中循环左移函数
221 void RotateL(int input[28],int output[28], int loop)
222 {
223     BitsCopy(output,input+loop,28-loop); 
224     BitsCopy(output+28-loop,input,loop);
225 }
226 
227 //子秘钥生成
228 void  subKey_fun(int input[64],int Subkey[16][48])
229 {
230     int i=0;
231     int temp[56];
232     int *KeyL=&temp[0],*KeyR=&temp[28];
233     printf("***子秘钥的生成:***\n");
234     PC_1(input,temp,PC1_Table);
235     printf("PC-1置换:\n"); 
236     ShowArray(temp,56);
237     
238     for(i=0;i<16;i++)
239     {    
240         printf("子秘钥第%d:\n",i+1);
241         RotateL(KeyL,KeyL,LOOP_Table[i]);       // 前28位左移 
242         printf("循环左移后左部:\n");
243         ShowArray(KeyL,28);
244         RotateL(KeyR,KeyR,LOOP_Table[i]);          // 后28位左移 
245         printf("循环左移后右部:\n");
246         ShowArray(KeyR,28);
247         PC_2(temp,Subkey[i],PC2_Table);
248         printf("PC-2选择置换:\n");
249         ShowArray(Subkey[i],48);
250          
251     }
252 }
253 
254 
255 /*----------------------------------
256  二进制密文转换为十六进制
257  需要16个字符表示
258 -----------------------------------*/
259 void BitToHex(char *DatOut,int *DatIn,int Num)
260 {
261     int i=0;
262     for(i=0;i4;i++)
263     {
264         DatOut[i]=0;
265     }
266     for(i=0;i4;i++)
267     {
268         DatOut[i] = DatIn[i*4]+(DatIn[i*4+1]<<1)
269                     +(DatIn[i*4+2]<<2)+(DatIn[i*4+3]<<3);
270         if((DatOut[i]%16)>9)
271         {
272             DatOut[i]=DatOut[i]%16+'7';       //  余数大于9时处理 10-15 to A-F
273         }                                     //  输出字符 
274         else
275         {
276             DatOut[i]=DatOut[i]%16+'0';       //  输出字符       
277         }
278     }
279     
280 }
281 
282 //DES加密
283 void  DES_Dfun(int input[],char key_in[],char output[])
284 {
285     int ML[32]={0},MR[32]={0};
286     int temp1[64],temp2[32],temp3[64];
287     int Subkey[16][48];
288     int input_l[32]={0};
289     int input_r[32]={0};
290     int testi=0;
291     for(testi=0;testi<32;testi++)
292     {
293         input_l[testi]=input[testi];
294     }
295     for(testi=0;testi<32;testi++)
296     {
297         input_r[testi]=input[32+testi];
298     }
299     BitsCopy(ML,input_l,32);
300     BitsCopy(MR,input_r,32);
301     BitsCopy(temp1,input,64);
302     IP_IPR(temp1,input,IP_Table); //IP置换
303     printf("IP初始置换:\n");
304     ShowArray(input,64);
305     CharToBit(key_in,temp3,64);
306     subKey_fun(temp3,Subkey);   //子秘钥的生成
307     for(int i=0;i<16;i++)                       // 迭代16次 
308     {
309         printf("***第%d轮迭代:***\n",i+1); 
310         BitsCopy(temp2,MR,32);            // 临时存储
311         F_func(MR,Subkey[i]);           // F函数变换
312         Xor(MR,ML,32);             // 得到Ri 
313         BitsCopy(ML,temp2,32);            // 得到Li 
314         printf("ML:\n");
315         ShowArray(ML,32);
316         printf("MR:\n");
317         ShowArray(MR,32);
318     }    
319     IP_IPR(input,temp1,IPR_Table);
320     BitToHex(output,input,64);
321 }
322 
323  //输出字符数组
324 void ShowArray(int *array,int num)
325 {
326     int i;
327     for(i=0;i)
328     {
329         printf("%d",array[i]);
330     }
331     printf("\n");
332 }
333 
334 int main()
335 {
336     int i=0; 
337      char MyKey[9]={0};           // 初始密钥 8字节*8
338     char MyMessage[9]={0};       // 初始明文 
339     int KeyBin[64]={0},MesBin[64]={0};
340     char ciphertext[9];
341 /*-----------------------------------------------*/
342     
343     printf("输入明文(8字节):\n");
344     gets(MyMessage);            // 明文
345     printf("输入密钥(8字节):\n");
346     gets(MyKey);                // 密钥
347     while(strlen(MyKey)!=8)                  // 不是8 提示错误
348     {
349         printf("请输入正确的密钥:\n");
350         gets(MyKey);
351         i=0;
352         while(MyKey[i]!='\0')    // 再次检测
353         {
354             i++;
355         }
356     }
357     CharToBit(MyMessage,MesBin,64);
358     DES_Dfun(MesBin,MyKey,ciphertext);
359     printf("明文已被加密!\n");  // 信息已加密
360     for(i=0;i<16;i++)           
361     {
362         printf("%c ",ciphertext[i]);
363     }
364     printf("\n");
365     system("pause");
366     return 0;
367 /*------------------------------------------------*/    
368 }

 

你可能感兴趣的:(DES加密的C语言实现)