您的位置:首页 > 编程语言 > C语言/C++

DES算法的介绍与C语言实现

2012-08-03 11:04 169 查看
2008-04-28 14:56

一、DES算法介绍

DES( Data Encryption Standard)算法,于1977年得到美国政府的正式许可,是一种用56位密钥来加密64位数据的方法。以下简要地介绍该算法的步骤。

A. 密钥生成

1、取得密钥


从用户处取得一个64位长的密码key ,去除64位密码中作为奇偶校验位的第8、16、24、32、40、48、56、64位,剩下的56位作为有效输入密钥。

2、 等分密钥



把生成的56位输入密钥分成均等的A,B两部分,每部分为28位,参照表1和表2把输入密钥的位置填入相应的位置。 按表1所示A的第一位为输入的64位密钥的第57位,A的第2位为64位密钥的第49位,……,依此类推,A的最后一位是64位密钥的第36位。

3、 密钥的移位



DES算法的密钥是经过16次迭代得到一组密钥的,把生成的A,B视为迭代的起始密钥,表3显示在第I次迭代时密钥循环左移的位数。 比如在第1次迭代时密钥循环左移1位,第3次迭代时密钥循环左移2位。 第9次迭代时密钥循环左移1位,第14次迭代时密钥循环左移2位。

4、 密钥的选取



把第I次迭代生成的两个28位长的密钥为合并,按表4所示k的第一位为56位密钥的第14位,k的第2位为56位密钥的第17位,……,依此类推,k的最后一位是56位密钥的第32位。 这样就得到子密钥K[I]。

5、迭代

DES算法密钥生成需要进行16次迭代,在完成16次迭代前,循环执行密钥的移位和密钥的选取。最终形成16个子密钥:K[0],K[1],……,[15]。

B. 数据的加密操作

1、 取得数据


把明文数据分成64位的数据块,不够64位的数据块以适当的方式补足。

2、 初始换位



按表5所示,把输入的64位数据的原第58位换到第一位,原第50位换到第二位,……,依此类推,最后的得到新的64位数据。

3 、数据扩展

第一次迭代以刚生成的新数据作为输入数据,第I(I > 1)次迭代以第I-1次的64位输出数据为输入数据,把64位数据按位置等分成左右两部分:left和right。

保持left不变,根据表6把right由32位扩展成48位



把扩展后的48位right与第I次迭代生成的48位子密钥,进行按位异或原是,形成一个新的48位的right。

4、 数据压缩

上面形成的48位的right值, 需要把它转换成32位的right值。把right视为由8个6位二进制组成, a,b,……,h都是6位,强制转换成10进制整数的值都不大于64 ,a,b,……,h转成10进制整数后,在对应的表中根据转换后整数值,取得对应位置的替代值, a对应表7.1,b对应表7.2,……,h对应表7.8。每6位用一个4位替换这样就完成了从48位向32位数据的转换。比如:

a = 32 ,那么到表7.1中找到32的位置,把对应的替代值0x8赋给a;

d = 53 ,那么到表7.4中找到的位置,把对应的替代值 0x3赋给d ;

g = 16, 那么到表7.7中找到16的位置,把对应的替代值0xa赋给g;



5 、数据换位

把上面形成的32位right,根据表8进行转换。数据的原第16位换到第一位,原第7位换到第二位,……,依此类推,最后得到新的32位数据。



6 、交换数据

把right 和left按位异或运算后的值赋给right,然后将本轮输入的原始right值赋给left。

7 、迭代

DES算法需要进行16次迭代,在完成16次迭代前,把第I-1次得到的left和right的值作为第I次的输入数据,重复3,4,5,6的步骤,但是有一点要记住:在步骤3中第I次迭代要选择第I次迭代生成的子密钥与数据进行按位异或运算。

8 、数据整理



为保证加密和解密的对称性,DES算法的前15次迭代每完成一次迭代都要交换left和right的值,第16次迭代不交换两者的数值。 到此把32位的left和right合并成64位的数据。

根据表9重新调整位置。数据的原第40位换到第一位,原第8位换到第二位,……,依此类推,最后的得到新的64位数据,即为密文。

C. 数据的解密

数据解密的算法与加密算法相同,区别在于和数据进行按位异或运算时,子密钥的使用顺序不同,在加密中是按照第I次迭代就采用第I次迭代生成的子密钥进行异或,而解密时第I次迭代就采用第15-I次迭代生成的密钥和数据进行异或。

二、算法的实现

以下是用c语言编写的基于DES算法的核心加密解密程序的接口函数。

1、加密函数

unsigned char enDES(unsigned char* indata,unsigned long inlen,unsigned char key[8],\

unsigned char* outdata,unsigned long* outlen);//加密

功能:本函数实现了根据初始密钥生成16个子密钥。把明文数据分割成64位的数据块,逐块实现16次循环迭代加密。密文数据放指针outdata所指向的内存中,它必须提前分配,并要求足够大(>inlen+8)。这是最简单的ECB模式的DES加密。

参数:

indata:指向明文数据的指针。

inlen:明文数据的长度。

key:用户输入的密钥。

outdata:存放密文数据的指针。

outlen:传入outdata内存的大小,传出密文数据的长度。

返回值:1-成功,0-失败。

unsigned char enDES_cbc(unsigned char* indata,unsigned long inlen,unsigned char key[8],\

unsigned char* outdata,unsigned long* outlen,unsigned char* iv);

功能:本函数实现了根据初始密钥生成16个子密钥。把明文数据分割成64位的数据块,逐块实现16次循环迭代加密。密文数据放指针outdata所指向的内存中,它必须提前分配,并要求足够大(>inlen+8)。这是CBC模式的DES加密。

参数:

indata:指向明文数据的指针。

inlen:明文数据的长度。

key:用户输入的密钥。

outdata:存放密文数据的指针。

outlen:传入outdata内存的大小,传出密文数据的长度。

返回值:1-成功,0-失败。

unsigned char enY5DES(gYan5DES* y5);

功能:本函数是专门为研五封装的加密接口。内部调用了enDES函数和base64编码的函数。

参数:

Y5:结构体指针。

返回值:1-成功,0-失败。

2、解密函数

unsigned char unDES(unsigned char* indata,unsigned long inlen,unsigned char key[8],\

unsigned char* outdata,unsigned long* outlen);//解密

功能:本函数实现了根据初始密钥生成16个子密钥。把密文数据分割成64位的数据块,逐块实现16次循环迭代解密。明文数据放指针outdata所指向的内存中,它必须提前分配,并要求足够大(>inlen+8)。这是最简单的ECB模式的DES加密。

参数:

indata:指向密文数据的指针。

inlen:密文数据的长度。

key:用户输入的密钥。

outdata:存放明文数据的指针。

outlen:传入outdata内存的大小,传出明文数据的长度。

返回值:1-成功,0-失败。

unsigned char* unDES_cbc(unsigned char* data,unsigned char* key,\

unsigned long inlen,unsigned long* outlen,char* iv);//解密

功能:本函数实现了根据初始密钥生成16个子密钥。把密文数据分割成64位的数据块,逐块实现16次循环迭代解密。明文数据放指针outdata所指向的内存中,它必须提前分配,并要求足够大(>inlen+8)。这是CBC模式的DES加密。

参数:

data:指向密文数据的指针。

key:用户输入的密钥。

inlen:密文数据的长度。

outlen:传入outdata内存的大小,传出明文数据的长度。

iv:初始向量。

返回值:1-成功,0-失败。

unsigned char unY5DES(gYan5DES* y5);

功能:本函数是专门为研五封装的解密接口。内部调用了base64解码的函数和unDES函数。

参数:

Y5:结构体指针。

返回值:1-成功,0-失败。

3、密钥生成函数

void randKey(unsigned char key[8]);//生成随机密钥

功能: 本函数调用编译器的参数随机数的函数,生成一个64位的随机密钥。由于随机数参产生器产生的不是真正的随机数,所以这种方法不可靠。

参数:

key[]:存放8字节二进制密钥的数组。

返回值:无返回值。

4、加密解密公共函数

unsigned char comDES(unsigned char in[8],unsigned char out[8],

unsigned char subkey[16][8],unsigned char flg);

功能:根据加密解密标志flg和16个48位的子密钥subkey。把64位的初始数据in,加密解密成64位的新数据out。

5、生成子密钥函数

void genKey(unsigned char*,unsigned char[16][8]);

功能:根据用户给出的一个64位密钥,产生16个48位的子密钥。

6、S盒代替函数

void sReplace(unsigned char*) ;

功能:实现S盒代替,把48位的数据压缩到32位。





DES算法的源代码

1、 程序源文件

//作者:高金山

//日期:2004年3月

//说明:本文件包含了DES加密解密的函数。

//循环移位表,PC-1表,PC-2表,IP表,IP-1表,

//E扩展表,P变换表,S盒等都可以自己设置

#define g_RUN_ON_PC//pc上运行的标志

#ifndef g_RUN_ON_PC

#include "release.h"

#else

#include "stdlib.h"

#define bmalloc malloc

#endif

#include "gjsDES.h"

void xTran(unsigned char q[8],unsigned char p[8],unsigned char xTab[],int xLen)

{//根据置换表xTab将64位q转换成p

int i,qt,pt,tt;//qt,pt分别表示q,p的第几个字节,tt暂存

for(i=0;i<8;i++)

p[i]=0;//先清零

for(i=0;i<xLen;i++)

{//循环置位

pt=i/8;

qt=(xTab[i]-1)/8;

tt=q[qt] << ((xTab[i]-1) % 8);

tt=tt & 0x80;//1000 0000

tt=tt >> (i % 8);

p[pt]=p[pt] | tt;

}

}

void genKey(unsigned char *key,unsigned char nkey[16][8])

{//由初始密钥okey生成16个子密钥nkey

unsigned char movebit[16]={//循环移位表。

1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

unsigned char pc_1[56]={//PC-1置换。

57,49,41,33,25,17,9,

1,58,50,42,34,26,18,

10,2,59,51,43,35,27,

19,11,3,60,52,44,36,

63,55,47,39,31,23,15,

7,62,54,46,38,30,22,

14,6,61,53,45,37,29,

21,13,5,28,20,12,4};

unsigned char pc_2[48]={//PC-2置换。

14,17,11,24,1,5,

3,28,15,6,21,10,

23,19,12,4,26,8,

16,7,27,20,13,2,

41,52,31,37,47,55,

30,40,51,45,33,48,

44,49,39,56,34,53,

46,42,50,36,29,32};

unsigned char tkey[8],tt[8];//暂存64字节

unsigned long key_c,key_d; //前28位,后28位

int i=0,j=0;

for(i=0;i<8;i++) tkey[i]=0;

i=0;//strcpy(tkey,key);

while((*(key+i)!='\0')&&(i<8))

{ tkey[i]=*(key+i);i++; }

xTran(tkey,tt,pc_1,56); //PC-1置换

key_c=(*(tt+0)<<24)+(*(tt+1)<<16)+(*(tt+2)<<8)+(*(tt+3));

key_c=key_c & 0xfffffff0;//将前28位移入key_c的高28位

key_d=(*(tt+3)<<24)+(*(tt+4)<<16)+(*(tt+5)<<8)+(*(tt+6));

key_d=key_d & 0x0fffffff;//将后28位移入key_d低28位

for(i=0;i<16;i++)

{ //移位以得到各个子密钥

//根据移位表对c,d进行循环左移

key_c=(key_c<<movebit[i]) | ((key_c>>(28-movebit[i])) & 0xfffffff0);

key_d=((key_d<<movebit[i])& 0x0fffffff) | (key_d>>(28-movebit[i]));

for(j=0;j<8;j++)

tt[j]=0;//清零

*(tt+0)=key_c>>24;*(tt+1)=key_c>>16;

*(tt+2)=key_c>>8;*(tt+3)=key_c;//合并c到tt

*(tt+3)|=(key_d>>24);*(tt+4)=key_d>>16;

*(tt+5)=key_d>>8;*(tt+6)=key_d;//合并d到tt

xTran(tt,nkey[i],pc_2,48);//PC-2置换

}

}//生产子密钥结束

void sReplace(unsigned char right_s[8])

{//查找S盒,把扩展成48位的数据,替换成32位的数据

unsigned char p[32]={//P置换。

16,7,20,21,

29,12,28,17,

1,15,23,26,

5,18,31,10,

2,8,24,14,

32,27,3,9,

19,13,30,6,

22,11,4,25 } ;

unsigned char s[][4][16] =

{{//S盒1。 S盒都可以自己设置

14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,

0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,

4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,

15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13 },

{//S盒2

15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,

3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,

0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,

13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9 },

{//S盒3

10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,

13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,

13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,

1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12 },

{//S盒4

7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,

13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,

10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,

3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14 },

{ //S盒5

2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,

14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,

4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,

11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3 },

{//S盒6

12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,

10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,

9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,

4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13 },

{//S盒7

4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,

13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,

1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,

6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12 },

{//S盒8

13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,

1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,

7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,

2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11 }};

unsigned char row,col,tmp_s[8]={0,0,0,0,0,0,0,0};

unsigned short tt;

int i=0;

for(i=0;i<=7;i++)

{//从S盒中取数

row=0,col=0;tt=0;

tt=((right_s[i*6/8]<<8) + (right_s[i*6/8+1])) >> (10-i*6 % 8);//取六位放到tt低6位

row=(row | ((tt>>5) & 0x01)) << 1;//取6位的第0位付给row的6位

row=(row | ((tt>>0) & 0x01)) << 0;//取6位的第5位付给row的7位

col=(tt >> 1) & 0x0f;//取6位的第1,2,3,4位付给row的低四位

//根据行和列的值从S盒中取数

tmp_s[i/2]=tmp_s[i/2]|s[i][row][col]<<4*((i+1)%2);

} //s_out[0-3]:???????? ???????? ???????? ???????? 00000000...

xTran(tmp_s,right_s,p,32); //P置换

}//S代替的结束

#define g_ENCRYPT_FLAG 1

#define g_DECRYPT_FLAG 2

unsigned char comDES(unsigned char in[8],unsigned char out[8],

unsigned char subkey[16][8],unsigned char flg)

{//单重DES加解密的公共函数 in输入数据 key密钥 out输出数据

unsigned char ip[64]={////IP置换。

58,50,42,34,26,18,10,2,

60,52,44,36,28,20,12,4,

62,54,46,38,30,22,14,6,

64,56,48,40,32,24,16,8,

57,49,41,33,25,17,9, 1,

59,51,43,35,27,19,11,3,

61,53,45,37,29,21,13,5,

63,55,47,39,31,23,15,7 };

unsigned char ip_1[64]={//IP-1置换。可根据IP表生成

40,8,48,16,56,24,64,32,

39,7,47,15,55,23,63,31,

38,6,46,14,54,22,62,30,

37,5,45,13,53,21,61,29,

36,4,44,12,52,20,60,28,

35,3,43,11,51,19,59,27,

34,2,42,10,50,18,58,26,

33,1,41,9, 49,17,57,25 };

unsigned char e[48] ={//E扩展。

32,1, 2, 3, 4, 5,

4, 5, 6, 7, 8, 9,

8, 9, 10,11,12,13,

12,13,14,15,16,17,

16,17,18,19,20,21,

20,21,22,23,24,25,

24,25,26,27,28,29,

28,29,30,31,32,1};

unsigned char left[8],right[8],temp[8];//数据的左32位,右32位,暂存

int i=0,j=0,k=0;

xTran(in,temp,ip,64); //IP置换

for(i=0;i<=3;i++) left[i]=temp[i] ;//将明文左32位放到left中

for(i=4;i<=7;i++) right[i-4]=temp[i] ;//将明文右32位放到right中

for(i=0;i<16;i++)

{//16层循环

if(flg==g_ENCRYPT_FLAG) k=i;

else if(flg==g_DECRYPT_FLAG) k=15-i;

else return 0;

for(j=0;j<=3;j++)

{

temp[j]=left[j];//将left暂存起来

left[j]=right[j];//L(n) = R(n-1)

}

xTran(left,right,e,48);//对right进行E扩展

for(j=0;j<6;j++)

right[j]=right[j]^subkey[k][j];//48位的数据右部与密钥异或

sReplace(right) ;//将48位的right变为32位

for(j=0;j<=3;j++)

{//获得下一个right

right[j]=temp[j] ^ right[j] ;//f(R(n-1),k)

}

}

for(i=0;i<4;i++) temp[i]=right[i]; //合并right和left到temp(64位)

for(i=4;i<8;i++) temp[i]=left[i-4];//右边左边互换,因为最后一次不用交换

//for(i=0;i<64;i++) ip_1[ip[i]-1]=i+1;//生成IP-1置换表

xTran(temp,out,ip_1,64);//IP-1置换

return 1;

}//单重DES加解密结束

//=======================================DES====================================

unsigned char enDES(unsigned char* indata,unsigned long inlen,unsigned char* key,\

unsigned char* outdata,unsigned long* outlen)

{//加密

unsigned char *p,*p1,s_key[16][8],tt[8];

long tlen=0,i=0,ttlen=0;

if((indata==NULL)||(outdata==NULL)||(key==NULL)

||(outlen==NULL)||(inlen<=0)||(*outlen<inlen))

return 0;//传入参数错误

p=indata;

tlen=inlen/8;

if(inlen%8!=0)

tlen=tlen+1;

tlen=tlen*8;//补整

*outlen=tlen;//密文长度

p1=outdata;tlen=inlen;

for(i=0;i<8;i++) tt[i]=0;

genKey(key,s_key);//获取16个子密钥

while(tlen>0)

{//逐64位循环加密

for(i=0;i<8;i++) tt[i]=0;

ttlen=(tlen<8)?tlen:8;

for(i=0;i<ttlen;i++)

tt[i]=*(p+i);//取原数据

comDES(tt,p1,s_key,g_ENCRYPT_FLAG);

p=p+8;p1=p1+8;tlen=tlen-8;

}

return 1;

}

unsigned char unDES(unsigned char* indata,unsigned long inlen,unsigned char* key,\

unsigned char* outdata,unsigned long* outlen)

{//解密

unsigned char *p,*p1,s_key[16][8],tt[8];

long tlen=0,i=0,ttlen=0;

if((indata==NULL)||(outdata==NULL)||(key==NULL)

||(outlen==NULL)||(inlen<=0)||(*outlen<inlen))

return 0;//传入参数错误

p=indata;

tlen=inlen/8;

if(inlen%8!=0)

tlen=tlen+1;

tlen=tlen*8;//补整

*outlen=tlen;//明文长度

p1=outdata;tlen=inlen;

for(i=0;i<8;i++) tt[i]=0;

genKey(key,s_key);//获取16个子密钥

while(tlen>0)

{//逐64位循环解密

for(i=0;i<8;i++) tt[i]=0;

ttlen=(tlen<8)?tlen:8;

for(i=0;i<ttlen;i++)

tt[i]=*(p+i);//取原数据

comDES(tt,p1,s_key,g_DECRYPT_FLAG);

p=p+8;p1=p1+8;tlen=tlen-8;

}

return 1;

}

//================随机生成密钥========================

void randKey(unsigned char key[8])

{//根随机生成一个64位(8字节)的密钥

unsigned char i;

for(i=0;i<8;i++)

key[i]=rand() % 0x0100;

};

//==============DES-CBC============================================================

unsigned char enDES_cbc(unsigned char* indata,unsigned long inlen,unsigned char* key,\

unsigned char* outdata,unsigned long* outlen,unsigned char* iv)

{//DES-CBC加密

unsigned char *p,*p1,s_key[16][8],tt[8],ivt[8];

long tlen=0,i=0,ttlen=0;

if((indata==NULL)||(outdata==NULL)||(key==NULL)||(iv==NULL)

||(outlen==NULL)||(inlen<=0)||(*outlen<inlen))

return 0;//传入参数错误

for(i=0;i<8;i++)

ivt[i]=iv[i];

p=indata;

tlen=inlen/8;

if(inlen%8!=0)

tlen=tlen+1;

tlen=tlen*8;//补整

*outlen=tlen;//密文长度

p1=outdata;tlen=inlen;

for(i=0;i<8;i++) tt[i]=0;

genKey(key,s_key);//获取16个子密钥

while(tlen>0)

{//逐64位循环加密

for(i=0;i<8;i++) tt[i]=0;

ttlen=(tlen<8)?tlen:8;

for(i=0;i<ttlen;i++)

tt[i]=*(p+i);//取原数据

for(i=0;i<8;i++)//与iv异或

tt[i]=tt[i] ^ ivt[i];

comDES(tt,p1,s_key,g_ENCRYPT_FLAG);

for(i=0;i<8;i++)

ivt[i]=p1[i];

p=p+8;p1=p1+8;tlen=tlen-8;

}

return 1;

}

unsigned char unDES_cbc(unsigned char* indata,unsigned long inlen,unsigned char* key,\

unsigned char* outdata,unsigned long* outlen,unsigned char* iv)

{//DES-CBC解密

unsigned char *p,*p1,s_key[16][8],tt[8],ivt[8];

long tlen=0,i=0,ttlen=0;

if((indata==NULL)||(outdata==NULL)||(key==NULL)||(iv==NULL)

||(outlen==NULL)||(inlen<=0)||(*outlen<inlen))

return 0;//传入参数错误

for(i=0;i<8;i++)

ivt[i]=iv[i];

p=indata;

tlen=inlen/8;

if(inlen%8!=0)

tlen=tlen+1;

tlen=tlen*8;//补整

*outlen=tlen;//明文长度

p1=outdata;tlen=inlen;

for(i=0;i<8;i++) tt[i]=0;

genKey(key,s_key);//获取16个子密钥

while(tlen>0)

{//逐64位循环解密

for(i=0;i<8;i++) tt[i]=0;

ttlen=(tlen<8)?tlen:8;

for(i=0;i<ttlen;i++)

tt[i]=*(p+i);//取原数据

comDES(tt,p1,s_key,g_DECRYPT_FLAG);

for(i=0;i<8;i++)//与iv异或

p1[i]=p1[i] ^ ivt[i];

for(i=0;i<8;i++)

ivt[i]=tt[i];

p=p+8;p1=p1+8;tlen=tlen-8;

}

return 1;

}

unsigned char enY5DES(gYan5DES* y5)

{//研五DES加密

int flag=0;

if((y5==NULL)||(y5->len>g_YAN5_DES_LEN)

||(y5->len==0)||(y5->len%8!=0))

return 0;//传入参数错误

flag=enDES(y5->indata,y5->len,y5->key,y5->outdata,&(y5->len));

if(flag) return 1;

else return 0;

}

unsigned char unY5DES(gYan5DES* y5)

{//研五DES解密

int flag=0;

if((y5==NULL)||(y5->len>g_YAN5_DES_LEN)

||(y5->len==0)||(y5->len%8!=0))

return 0;//传入参数错误

flag=unDES(y5->indata,y5->len,y5->key,y5->outdata,&(y5->len));

if(flag) return 1;

else return 0;

}

void clrYan5DES(gYan5DES* y5)

{//清空结构

int i=0;

if(y5==NULL) return;

for(i=0;i<g_YAN5_DES_LEN;i++)

{

y5->indata[i]=0;

y5->outdata[i]=0;

}

for(i=0;i<8;i++)

y5->key[i]=0;

y5->len=0;

}

2、 程序头文件

#ifndef _GJS_DES_H

#define _GJS_DES_H

//====================研5专用接口=======================

#define g_YAN5_DES_LEN 128

typedef struct g_Yan5DES

{//研五加解密专用结构

unsigned char indata[g_YAN5_DES_LEN];

unsigned char outdata[g_YAN5_DES_LEN];

unsigned char key[8];

unsigned long len;

} gYan5DES;

unsigned char enY5DES(gYan5DES* y5);//加密

unsigned char unY5DES(gYan5DES* y5);//解密

void clrYan5DES(gYan5DES* y5);

//====================CBC-DES和ECB-DES接口=====================

unsigned char enDES_cbc(unsigned char* indata,unsigned long inlen,unsigned char key[8],\

unsigned char* outdata,unsigned long* outlen,unsigned char* iv);//加密

unsigned char unDES_cbc(unsigned char* indata,unsigned long inlen,unsigned char key[8],\

unsigned char* outdata,unsigned long* outlen,unsigned char* iv);//解密

unsigned char enDES(unsigned char* indata,unsigned long inlen,unsigned char key[8],\

unsigned char* outdata,unsigned long* outlen);//加密

unsigned char unDES(unsigned char* indata,unsigned long inlen,unsigned char key[8],\

unsigned char* outdata,unsigned long* outlen);//解密

void randKey(unsigned char key[8]);//生成随机密钥

//====================以下函数自己调用========================

//加解密的公共函数

unsigned char comDES(unsigned char in[8],unsigned char out[8],\

unsigned char subkey[16][8],unsigned char flg);

//生成16个子密钥(48位有效)

void genKey(unsigned char*,unsigned char[16][8]);

//S盒代替和P置换(48位->32位)

void sReplace(unsigned char*) ;

#endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: