DES加密的C语言实现

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

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

  1 #include<stdio.h>
  2 #include<stdlib.h>
  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<bits;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<bits;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<len;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<Len;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;i<Num/4;i++)
263     {
264         DatOut[i]=0;
265     }
266     for(i=0;i<Num/4;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<num;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 }
时间: 2024-11-11 19:33:18

DES加密的C语言实现的相关文章

关于 Des加密(Android与ios 与后台java服务器之间的加密解密)

关于 Des加密(Android与ios  与后台java服务器之间的加密解密) http://blog.sina.com.cn/s/blog_7c8dc2d50101id91.html (2013-04-17 11:47:23)   分类: iPhone开发 最近做了一个移动项目,是有服务器和客户端类型的项目,客户端是要登录才行的,登录的密码要用DES加密,服务器是用Java开发的,客户端要同时支持多平台(Android.iOS),在处理iOS的DES加密的时候遇到了一些问题,起初怎么调都调不

兼容PHP和Java的des加密解密代码分享

这篇文章主要介绍了兼容PHP和Java的des加密解密代码分享,适合如服务器是JAVA语言编写,客户端是PHP编写,并需要des加密解密的情况,需要的朋友可以参考下 php <?php class DES { var $key; var $iv; //偏移量 function DES($key, $iv=0) { $this->key = $key; if($iv == 0) { $this->iv = $key; } else { $this->iv = $iv; } } //加

关于Objective-c和Java下DES加密保持一致的方式

转载自:http://www.cnblogs.com/janken/archive/2012/04/05/2432930.html 最近做了一个移动项目,是有服务器和客户端类型的项目,客户端是要登录才行的,登录的密码要用DES加密,服务器是用Java开发的,客户端要同时支持多平台(Android.iOS),在处理iOS的DES加密的时候遇到了一些问题,起初怎么调都调不成和Android端生成的密文相同.最终一个忽然的想法让我找到了问题的所在,现在将代码总结一下,以备自己以后查阅. 首先,Java

C# DES加密类,16位的加密。

这个加密类是与java写的DES加密不同时,自己写的,最后与Java的加密相同了,解决了加密后不同的问题. 可以直接调用里面的加密和解密的方法. using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Text; using System.Security.Cryptography; using System.IO; namespace EallNum.He

C#DES加密解密字符串

1.添加引用 using System.Security.Cryptography; using System.IO; 2.添加默认密匙向量 //默认密钥向量 private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; 3.添加加密解密类 /// <summary> /// DES加密字符串 /// </summary> /// <param name="encry

DES加密解密算法

DES加密解密算法 // 仿射变换加解密.cpp : 定义控制台应用程序的入口点. // #include <stdio.h> #include <conio.h> static char key[10], key_a[5], code[8], key_b[5], temp[10], key_aa[8], key_bb[8], l[4], r[4], l_a[4], r_a[4], V[8] = { 0, 1, 0, 1, 0, 1, 0, 1 }, b[8]; char Code

Oracle定义DES加密解密及MD5加密函数

http://blog.csdn.net/xdweleven/article/details/38319351 (1)DES加密函数create or replace functionencrypt_des(p_text varchar2, p_key varchar2) return varchar2 is        v_text varchar2(4000);        v_enc varchar2(4000);        raw_input RAW(128) ;       

pyDes库 实现python的des加密

下载及简介地址:https://twhiteman.netfirms.com/des.html 如需要在python中使用des加密,可以直接使用pyDes库加密,该库提供了CBC和ECB两种加密方式. 1.Windows下安装 下载后pyDes-x.x.x.zip并解压后,里面有setup.py文件,使用命令 setup.py --help可查看详细使用. 你可以使用命令 python setup.py install 命令安装,也可以直接将压缩包内的pyDes.py拷贝到本地的python

des加密解密——java加密,php解密

最近在做项目中,遇到des加密解密的问题. 场景是安卓app端用des加密,php这边需要解密.之前没有接触过des这种加密解密算法,但想着肯定会有demo.因此百度,搜了代码来用.网上代码也是鱼龙混杂,好不容易测试在php这边测试加密和解密成功了.为确保安卓app端提交过来的加密参数能够解密出来,给定安卓人员一个字符串,让他们把des加密后的字符串给我,在php这边解密.结果一看,加密出来的字符串跟我这边加密出来的结果不一致,自然是解密不出来. 要来java的des算法代码,研究加密的过程,其