DES使用56位密钥对64位的数据块进行加密,并对64位的数据块进行16轮编码。
与每轮编码时,一个48位的“每轮”密钥值由56位的完整密钥得出来。
DES用软件进行解码需要用很长时间,而用硬件解码速度非常快。
但幸运的是当时大多数黑客并没有足够的设备制造出这种硬件设备。
在1977年,人们估计要耗资两千万美元才能建成一个专门计算机用于DES的解密。
而且需要12个小时的破解才能得到结果。
所以,当时DES被认为是一种十分强壮的加密方法。
1. 用密钥K1进行DEA加密。
2. 用K2对步骤1的结果进行DES解密。
3. 用步骤2的结果使用密钥K1进行DES加密。
这种方法的缺点,是要花费原来三倍时间,从另一方面来看,三重DES的112位密钥长度是很“强壮”的加密方式了
❷ 对称加密算法中,des算法的密钥长度是多少,采用什么进行加密
DES使用56位密钥对64位的数据块进行加密,并对64位的数据块进行16轮编码。与每轮编码时,一个48位的“每轮”密钥值由56位的完整密钥得出来。DES用软件进行解码需要用很长时间,而用硬件解码速度非常快,但幸运的是当时大多数黑客并没有足够的设备制造出这种硬件设备。在1977年,人们估计要耗资两千万美元才能建成一个专门计算机用于DES的解密,而且需要12个小时的破解才能得到结果。所以,当时DES被认为是一种十分强壮的加密方法。
但是,当今的计算机速度越来越快了,制造一台这样特殊的机器的花费已经降到了十万美元左右,所以用它来保护十亿美元的银行间线缆时,就会仔细考虑了。另一个方面,如果只用它来保护一台服务器,那么DES确实是一种好的办法,因为黑客绝不会仅仅为入侵一个服务器而花那么多的钱破解DES密文。由于现在已经能用二十万美圆制造一台破译DES的特殊的计算机,所以现在再对要求“强壮”加密的场合已经不再适用了。
三重DES
因为确定一种新的加密法是否真的安全是极为困难的,而且DES的唯一密码学缺点,就是密钥长度相对比较短,所以人们并没有放弃使用DES,而是想出了一个解决其长度问题的方法,即采用三重DES。这种方法用两个密钥对明文进行三次加密,假设两个密钥是K1和K2,其算法的步骤如图5.9所示:
1. 用密钥K1进行DEA加密。
2. 用K2对步骤1的结果进行DES解密。
3. 用步骤2的结果使用密钥K1进行DES加密。
这种方法的缺点,是要花费原来三倍时间,从另一方面来看,三重DES的112位密钥长度是很“强壮”的加密方式了
❸ 关于DES加密算法
数据加密算法
数据加密算法DES
数据加密算法(Data Encryption Algorithm,DEA)的数据加密标准(Data Encryption Standard,DES)是规范的描述,它出自 IBM 的研究工作,并在 1997 年被美国政府正式采纳。它很可能是使用最广泛的秘钥系统,特别是在保护金融数据的安全中,最初开发的 DES 是嵌入硬 件中的。通常,自动取款机(Automated Teller Machine,ATM)都使用 DES。
DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小。这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。使用子密钥对其中一半应用循环功能,然后将输出与另一半进行“异或”运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。DES 使用 16 个循环。
攻击 DES 的主要形式被称为蛮力的或彻底密钥搜索,即重复尝试各种密钥直到有一个符合为止。如果 DES 使用 56 位的密钥,则可能的密钥数量是 2 的 56 次方个。随着计算机系统能力的不断发展,DES 的安全性比它刚出现时会弱得多,然而从非关键性质的实际出发,仍可以认为它是足够的。不过 ,DES 现在仅用于旧系统的鉴定,而更多地选择新的加密标准 — 高级加密标准(Advanced Encryption Standard,AES)。
DES 的常见变体是三重 DES,使用 168 位的密钥对资料进行三次加密的一种机制;它通常(但非始终)提供极其强大的安全性。如果三个 56 位的子元素都相同,则三重 DES 向后兼容 DES。
IBM 曾对 DES 拥有几年的专利权,但是在 1983 年已到期,并且处于公有范围中,允许在特定条件下可以免除专利使用费而使用。
❹ des加密算法(c/c++)
des.h文件:
#ifndefCRYPTOPP_DES_H
#defineCRYPTOPP_DES_H
#include"cryptlib.h"
#include"misc.h"
NAMESPACE_BEGIN(CryptoPP)
classDES:publicBlockTransformation
{
public:
DES(constbyte*userKey,CipherDir);
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const
{DES::ProcessBlock(inoutBlock,inoutBlock);}
enum{KEYLENGTH=8,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
protected:
staticconstword32Spbox[8][64];
SecBlock<word32>k;
};
classDESEncryption:publicDES
{
public:
DESEncryption(constbyte*userKey)
:DES(userKey,ENCRYPTION){}
};
classDESDecryption:publicDES
{
public:
DESDecryption(constbyte*userKey)
:DES(userKey,DECRYPTION){}
};
classDES_EDE_Encryption:publicBlockTransformation
{
public:
DES_EDE_Encryption(constbyte*userKey)
:e(userKey,ENCRYPTION),d(userKey+DES::KEYLENGTH,DECRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=16,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESe,d;
};
classDES_EDE_Decryption:publicBlockTransformation
{
public:
DES_EDE_Decryption(constbyte*userKey)
:d(userKey,DECRYPTION),e(userKey+DES::KEYLENGTH,ENCRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=16,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESd,e;
};
classTripleDES_Encryption:publicBlockTransformation
{
public:
TripleDES_Encryption(constbyte*userKey)
:e1(userKey,ENCRYPTION),d(userKey+DES::KEYLENGTH,DECRYPTION),
e2(userKey+2*DES::KEYLENGTH,ENCRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=24,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESe1,d,e2;
};
classTripleDES_Decryption:publicBlockTransformation
{
public:
TripleDES_Decryption(constbyte*userKey)
:d1(userKey+2*DES::KEYLENGTH,DECRYPTION),e(userKey+DES::KEYLENGTH,ENCRYPTION),
d2(userKey,DECRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=24,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESd1,e,d2;
};
NAMESPACE_END
#endif
des.cpp文件:
//des.cpp-modifiedbyWeiDaifrom:
/*
*
*circa1987,'s1977
*publicdomaincode.,but
*theactualencrypt/
*Outerbridge'sDEScodeasprintedinSchneier's"AppliedCryptography."
*
*Thiscodeisinthepublicdomain.Iwouldappreciatebugreportsand
*enhancements.
*
*PhilKarnKA9Q,[email protected],August1994.
*/
#include"pch.h"
#include"misc.h"
#include"des.h"
NAMESPACE_BEGIN(CryptoPP)
/*
*Threeofthesetables,theinitialpermutation,thefinal
*,areregularenoughthat
*forspeed,wehard-codethem.They'rehereforreferenceonly.
*Also,,gensp.c,
*tobuildthecombinedSPbox,Spbox[].They'realsoherejust
*forreference.
*/
#ifdefnotdef
/*initialpermutationIP*/
staticbyteip[]={
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
};
/*finalpermutationIP^-1*/
staticbytefp[]={
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
};
/*expansionoperationmatrix*/
staticbyteei[]={
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
};
/*The(in)famousS-boxes*/
staticbytesbox[8][64]={
/*S1*/
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,
/*S2*/
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,
/*S3*/
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,
/*S4*/
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,
/*S5*/
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,
/*S6*/
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,
/*S7*/
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,
/*S8*/
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
};
/*32--boxes*/
staticbytep32i[]={
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
};
#endif
/*permutedchoicetable(key)*/
staticconstbytepc1[]={
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
};
/*numberleftrotationsofpc1*/
staticconstbytetotrot[]={
1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
};
/*permutedchoicekey(table)*/
staticconstbytepc2[]={
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
};
/*EndofDES-definedtables*/
/*bit0isleft-mostinbyte*/
staticconstintbytebit[]={
0200,0100,040,020,010,04,02,01
};
/*Setkey(initializekeyschelearray)*/
DES::DES(constbyte*key,CipherDirdir)
:k(32)
{
SecByteBlockbuffer(56+56+8);
byte*constpc1m=buffer;/*placetomodifypc1into*/
byte*constpcr=pc1m+56;/*placetorotatepc1into*/
byte*constks=pcr+56;
registerinti,j,l;
intm;
for(j=0;j<56;j++){/*convertpc1tobitsofkey*/
l=pc1[j]-1;/*integerbitlocation*/
m=l&07;/*findbit*/
pc1m[j]=(key[l>>3]&/*findwhichkeybytelisin*/
bytebit[m])/*andwhichbitofthatbyte*/
?1:0;/*andstore1-bitresult*/
}
for(i=0;i<16;i++){/*keychunkforeachiteration*/
memset(ks,0,8);/*Clearkeyschele*/
for(j=0;j<56;j++)/*rotatepc1therightamount*/
pcr[j]=pc1m[(l=j+totrot[i])<(j<28?28:56)?l:l-28];
/**/
for(j=0;j<48;j++){/*selectbitsindivially*/
/*checkbitthatgoestoks[j]*/
if(pcr[pc2[j]-1]){
/*maskitinifit'sthere*/
l=j%6;
ks[j/6]|=bytebit[l]>>2;
}
}
/*Nowconverttoodd/eveninterleavedformforuseinF*/
k[2*i]=((word32)ks[0]<<24)
|((word32)ks[2]<<16)
|((word32)ks[4]<<8)
|((word32)ks[6]);
k[2*i+1]=((word32)ks[1]<<24)
|((word32)ks[3]<<16)
|((word32)ks[5]<<8)
|((word32)ks[7]);
}
if(dir==DECRYPTION)//reversekeyscheleorder
for(i=0;i<16;i+=2)
{
std::swap(k[i],k[32-2-i]);
std::swap(k[i+1],k[32-1-i]);
}
}
/**/
/*Ccodeonlyinportableversion*/
//RichardOuterbridge'sinitialpermutationalgorithm
/*
inlinevoidIPERM(word32&left,word32&right)
{
word32work;
work=((left>>4)^right)&0x0f0f0f0f;
right^=work;
left^=work<<4;
work=((left>>16)^right)&0xffff;
right^=work;
left^=work<<16;
work=((right>>2)^left)&0x33333333;
left^=work;
right^=(work<<2);
work=((right>>8)^left)&0xff00ff;
left^=work;
right^=(work<<8);
right=rotl(right,1);
work=(left^right)&0xaaaaaaaa;
left^=work;
right^=work;
left=rotl(left,1);
}
inlinevoidFPERM(word32&left,word32&right)
{
word32work;
right=rotr(right,1);
work=(left^right)&0xaaaaaaaa;
left^=work;
right^=work;
left=rotr(left,1);
work=((left>>8)^right)&0xff00ff;
right^=work;
left^=work<<8;
work=((left>>2)^right)&0x33333333;
right^=work;
left^=work<<2;
work=((right>>16)^left)&0xffff;
left^=work;
right^=work<<16;
work=((right>>4)^left)&0x0f0f0f0f;
left^=work;
right^=work<<4;
}
*/
//WeiDai''sinitialpermutation
//algorithm,
//(likeinMSVC)
inlinevoidIPERM(word32&left,word32&right)
{
word32work;
right=rotl(right,4U);
work=(left^right)&0xf0f0f0f0;
left^=work;
right=rotr(right^work,20U);
work=(left^right)&0xffff0000;
left^=work;
right=rotr(right^work,18U);
work=(left^right)&0x33333333;
left^=work;
right=rotr(right^work,6U);
work=(left^right)&0x00ff00ff;
left^=work;
right=rotl(right^work,9U);
work=(left^right)&0xaaaaaaaa;
left=rotl(left^work,1U);
right^=work;
}
inlinevoidFPERM(word32&left,word32&right)
{
word32work;
right=rotr(right,1U);
work=(left^right)&0xaaaaaaaa;
right^=work;
left=rotr(left^work,9U);
work=(left^right)&0x00ff00ff;
right^=work;
left=rotl(left^work,6U);
work=(left^right)&0x33333333;
right^=work;
left=rotl(left^work,18U);
work=(left^right)&0xffff0000;
right^=work;
left=rotl(left^work,20U);
work=(left^right)&0xf0f0f0f0;
right^=work;
left=rotr(left^work,4U);
}
//
voidDES::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
word32l,r,work;
#ifdefIS_LITTLE_ENDIAN
l=byteReverse(*(word32*)inBlock);
r=byteReverse(*(word32*)(inBlock+4));
#else
l=*(word32*)inBlock;
r=*(word32*)(inBlock+4);
#endif
IPERM(l,r);
constword32*kptr=k;
for(unsignedi=0;i<8;i++)
{
work=rotr(r,4U)^kptr[4*i+0];
l^=Spbox[6][(work)&0x3f]
^Spbox[4][(work>>8)&0x3f]
^Spbox[2][(work>>16)&0x3f]
^Spbox[0][(work>>24)&0x3f];
work=r^kptr[4*i+1];
l^=Spbox[7][(work)&0x3f]
^Spbox[5][(work>>8)&0x3f]
^Spbox[3][(work>>16)&0x3f]
^Spbox[1][(work>>24)&0x3f];
work=rotr(l,4U)^kptr[4*i+2];
r^=Spbox[6][(work)&0x3f]
^Spbox[4][(work>>8)&0x3f]
^Spbox[2][(work>>16)&0x3f]
^Spbox[0][(work>>24)&0x3f];
work=l^kptr[4*i+3];
r^=Spbox[7][(work)&0x3f]
^Spbox[5][(work>>8)&0x3f]
^Spbox[3][(work>>16)&0x3f]
^Spbox[1][(work>>24)&0x3f];
}
FPERM(l,r);
#ifdefIS_LITTLE_ENDIAN
*(word32*)outBlock=byteReverse(r);
*(word32*)(outBlock+4)=byteReverse(l);
#else
*(word32*)outBlock=r;
*(word32*)(outBlock+4)=l;
#endif
}
voidDES_EDE_Encryption::ProcessBlock(byte*inoutBlock)const
{
e.ProcessBlock(inoutBlock);
d.ProcessBlock(inoutBlock);
e.ProcessBlock(inoutBlock);
}
voidDES_EDE_Encryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
e.ProcessBlock(inBlock,outBlock);
d.ProcessBlock(outBlock);
e.ProcessBlock(outBlock);
}
voidDES_EDE_Decryption::ProcessBlock(byte*inoutBlock)const
{
d.ProcessBlock(inoutBlock);
e.ProcessBlock(inoutBlock);
d.ProcessBlock(inoutBlock);
}
voidDES_EDE_Decryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
d.ProcessBlock(inBlock,outBlock);
e.ProcessBlock(outBlock);
d.ProcessBlock(outBlock);
}
voidTripleDES_Encryption::ProcessBlock(byte*inoutBlock)const
{
e1.ProcessBlock(inoutBlock);
d.ProcessBlock(inoutBlock);
e2.ProcessBlock(inoutBlock);
}
voidTripleDES_Encryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
e1.ProcessBlock(inBlock,outBlock);
d.ProcessBlock(outBlock);
e2.ProcessBlock(outBlock);
}
voidTripleDES_Decryption::ProcessBlock(byte*inoutBlock)const
{
d1.ProcessBlock(inoutBlock);
e.ProcessBlock(inoutBlock);
d2.ProcessBlock(inoutBlock);
}
voidTripleDES_Decryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
d1.ProcessBlock(inBlock,outBlock);
e.ProcessBlock(outBlock);
d2.ProcessBlock(outBlock);
}
NAMESPACE_END
程序运行如下:
❺ des算法加密解密的实现
本文介绍了一种国际上通用的加密算法—DES算法的原理,并给出了在VC++6.0语言环境下实现的源代码。最后给出一个示例,以供参考。
关键字:DES算法、明文、密文、密钥、VC;
本文程序运行效果图如下:
正文:
当今社会是信息化的社会。为了适应社会对计算机数据安全保密越来越高的要求,美国国家标准局(NBS)于1997年公布了一个由IBM公司研制的一种加密算法,并且确定为非机要部门使用的数据加密标准,简称DES(Data Encrypton Standard)。自公布之日起,DES算法作为国际上商用保密通信和计算机通信的最常用算法,一直活跃在国际保密通信的舞台上,扮演了十分突出的角色。现将DES算法简单介绍一下,并给出实现DES算法的VC源代码。
DES算法由加密、解密和子密钥的生成三部分组成。
一.加密
DES算法处理的数据对象是一组64比特的明文串。设该明文串为m=m1m2…m64 (mi=0或1)。明文串经过64比特的密钥K来加密,最后生成长度为64比特的密文E。其加密过程图示如下:
DES算法加密过程
对DES算法加密过程图示的说明如下:待加密的64比特明文串m,经过IP置换后,得到的比特串的下标列表如下:
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
该比特串被分为32位的L0和32位的R0两部分。R0子密钥K1(子密钥的生成将在后面讲)经过变换f(R0,K1)(f变换将在下面讲)输出32位的比特串f1,f1与L0做不进位的二进制加法运算。运算规则为:
f1与L0做不进位的二进制加法运算后的结果赋给R1,R0则原封不动的赋给L1。L1与R0又做与以上完全相同的运算,生成L2,R2…… 一共经过16次运算。最后生成R16和L16。其中R16为L15与f(R15,K16)做不进位二进制加法运算的结果,L16是R15的直接赋值。
R16与L16合并成64位的比特串。值得注意的是R16一定要排在L16前面。R16与L16合并后成的比特串,经过置换IP-1后所得比特串的下标列表如下:
IP-1 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
经过置换IP-1后生成的比特串就是密文e.。
下面再讲一下变换f(Ri-1,Ki)。
它的功能是将32比特的输入再转化为32比特的输出。其过程如图所示:
对f变换说明如下:输入Ri-1(32比特)经过变换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 31
膨胀后的比特串分为8组,每组6比特。各组经过各自的S盒后,又变为4比特(具体过程见后),合并后又成为32比特。该32比特经过P变换后,其下标列表如下:
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
经过P变换后输出的比特串才是32比特的f (Ri-1,Ki)。
下面再讲一下S盒的变换过程。任取一S盒。见图:
在其输入b1,b2,b3,b4,b5,b6中,计算出x=b1*2+b6, y=b5+b4*2+b3*4+b2*8,再从Si表中查出x 行,y 列的值Sxy。将Sxy化为二进制,即得Si盒的输出。(S表如图所示)
至此,DES算法加密原理讲完了。在VC++6.0下的程序源代码为:
for(i=1;i<=64;i++)
m1[i]=m[ip[i-1]];//64位明文串输入,经过IP置换。
下面进行迭代。由于各次迭代的方法相同只是输入输出不同,因此只给出其中一次。以第八次为例://进行第八次迭代。首先进行S盒的运算,输入32位比特串。
for(i=1;i<=48;i++)//经过E变换扩充,由32位变为48位
RE1[i]=R7[E[i-1]];
for(i=1;i<=48;i++)//与K8按位作不进位加法运算
RE1[i]=RE1[i]+K8[i];
for(i=1;i<=48;i++)
{
if(RE1[i]==2)
RE1[i]=0;
}
for(i=1;i<7;i++)//48位分成8组
{
s11[i]=RE1[i];
s21[i]=RE1[i+6];
s31[i]=RE1[i+12];
s41[i]=RE1[i+18];
s51[i]=RE1[i+24];
s61[i]=RE1[i+30];
s71[i]=RE1[i+36];
s81[i]=RE1[i+42];
}//下面经过S盒,得到8个数。S1,s2,s3,s4,s5,s6,s7,s8分别为S表
s[1]=s1[s11[6]+s11[1]*2][s11[5]+s11[4]*2+s11[3]*4+s11[2]*8];
s[2]=s2[s21[6]+s21[1]*2][s21[5]+s21[4]*2+s21[3]*4+s21[2]*8];
s[3]=s3[s31[6]+s31[1]*2][s31[5]+s31[4]*2+s31[3]*4+s31[2]*8];
s[4]=s4[s41[6]+s41[1]*2][s41[5]+s41[4]*2+s41[3]*4+s41[2]*8];
s[5]=s5[s51[6]+s51[1]*2][s51[5]+s51[4]*2+s51[3]*4+s51[2]*8];
s[6]=s6[s61[6]+s61[1]*2][s61[5]+s61[4]*2+s61[3]*4+s61[2]*8];
s[7]=s7[s71[6]+s71[1]*2][s71[5]+s71[4]*2+s71[3]*4+s71[2]*8];
s[8]=s8[s81[6]+s81[1]*2][s81[5]+s81[4]*2+s81[3]*4+s81[2]*8];
for(i=0;i<8;i++)//8个数变换输出二进制
{
for(j=1;j<5;j++)
{
temp[j]=s[i+1]%2;
s[i+1]=s[i+1]/2;
}
for(j=1;j<5;j++)
f[4*i+j]=temp[5-j];
}
for(i=1;i<33;i++)//经过P变换
frk[i]=f[P[i-1]];//S盒运算完成
for(i=1;i<33;i++)//左右交换
L8[i]=R7[i];
for(i=1;i<33;i++)//R8为L7与f(R,K)进行不进位二进制加法运算结果
{
R8[i]=L7[i]+frk[i];
if(R8[i]==2)
R8[i]=0;
}
[ 原创文档 本文适合中级读者 已阅读21783次 ] 文档 代码 工具
DES算法及其在VC++6.0下的实现(下)
作者:航天医学工程研究所四室 朱彦军
在《DES算法及其在VC++6.0下的实现(上)》中主要介绍了DES算法的基本原理,下面让我们继续:
二.子密钥的生成
64比特的密钥生成16个48比特的子密钥。其生成过程见图:
子密钥生成过程具体解释如下:
64比特的密钥K,经过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
该比特串分为长度相等的比特串C0和D0。然后C0和D0分别循环左移1位,得到C1和D1。C1和D1合并起来生成C1D1。C1D1经过PC-2变换后即生成48比特的K1。K1的下标列表为:
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
C1、D1分别循环左移LS2位,再合并,经过PC-2,生成子密钥K2……依次类推直至生成子密钥K16。
注意:Lsi (I =1,2,….16)的数值是不同的。具体见下表:
迭代顺序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
左移位数 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1
生成子密钥的VC程序源代码如下:
for(i=1;i<57;i++)//输入64位K,经过PC-1变为56位 k0[i]=k[PC_1[i-1]];
56位的K0,均分为28位的C0,D0。C0,D0生成K1和C1,D1。以下几次迭代方法相同,仅以生成K8为例。 for(i=1;i<27;i++)//循环左移两位
{
C8[i]=C7[i+2];
D8[i]=D7[i+2];
}
C8[27]=C7[1];
D8[27]=D7[1];
C8[28]=C7[2];
D8[28]=D7[2];
for(i=1;i<=28;i++)
{
C[i]=C8[i];
C[i+28]=D8[i];
}
for(i=1;i<=48;i++)
K8[i]=C[PC_2[i-1]];//生成子密钥k8
注意:生成的子密钥不同,所需循环左移的位数也不同。源程序中以生成子密钥 K8为例,所以循环左移了两位。但在编程中,生成不同的子密钥应以Lsi表为准。
三.解密
DES的解密过程和DES的加密过程完全类似,只不过将16圈的子密钥序列K1,K2……K16的顺序倒过来。即第一圈用第16个子密钥K16,第二圈用K15,其余类推。
第一圈:
加密后的结果
L=R15, R=L15⊕f(R15,K16)⊕f(R15,K16)=L15
同理R15=L14⊕f(R14,K15), L15=R14。
同理类推:
得 L=R0, R=L0。
其程序源代码与加密相同。在此就不重写。
四.示例
例如:已知明文m=learning, 密钥 k=computer。
明文m的ASCII二进制表示:
m= 01101100 01100101 01100001 01110010
01101110 01101001 01101110 01100111
密钥k的ASCII二进制表示:
k=01100011 01101111 01101101 01110000
01110101 01110100 01100101 01110010
明文m经过IP置换后,得:
11111111 00001000 11010011 10100110 00000000 11111111 01110001 11011000
等分为左右两段:
L0=11111111 00001000 11010011 10100110 R0=00000000 11111111 01110001 11011000
经过16次迭代后,所得结果为:
L1=00000000 11111111 01110001 11011000 R1=00110101 00110001 00111011 10100101
L2=00110101 00110001 00111011 10100101 R2=00010111 11100010 10111010 10000111
L3=00010111 11100010 10111010 10000111 R3=00111110 10110001 00001011 10000100
L4= R4=
L5= R5=
L6= R6=
L7= R7=
L8= R8=
L9= R9=
L10= R10=
L11= R11=
L12= R12=
L13= R13=
L14= R14=
L15= R15=
L16= R16=
其中,f函数的结果为:
f1= f2=
f3= f4=
f5= f6=
f7= f8=
f9= f10=
f11= f12=
f13= f14=
f15= f16=
16个子密钥为:
K1= K2=
K3= K4=
K5= K6=
K7= K8=
K9= K10=
K11= K12=
K13= K14=
K15= K16=
S盒中,16次运算时,每次的8 个结果为:
第一次:5,11,4,1,0,3,13,9;
第二次:7,13,15,8,12,12,13,1;
第三次:8,0,0,4,8,1,9,12;
第四次:0,7,4,1,7,6,12,4;
第五次:8,1,0,11,5,0,14,14;
第六次:14,12,13,2,7,15,14,10;
第七次:12,15,15,1,9,14,0,4;
第八次:15,8,8,3,2,3,14,5;
第九次:8,14,5,2,1,15,5,12;
第十次:2,8,13,1,9,2,10,2;
第十一次:10,15,8,2,1,12,12,3;
第十二次:5,4,4,0,14,10,7,4;
第十三次:2,13,10,9,2,4,3,13;
第十四次:13,7,14,9,15,0,1,3;
第十五次:3,1,15,5,11,9,11,4;
第十六次:12,3,4,6,9,3,3,0;
子密钥生成过程中,生成的数值为:
C0=0000000011111111111111111011 D0=1000001101110110000001101000
C1=0000000111111111111111110110 D1=0000011011101100000011010001
C2=0000001111111111111111101100 D2=0000110111011000000110100010
C3=0000111111111111111110110000 D3=0011011101100000011010001000
C4=0011111111111111111011000000 D4=1101110110000001101000100000
C5=1111111111111111101100000000 D5=0111011000000110100010000011
C6=1111111111111110110000000011 D6=1101100000011010001000001101
C7=1111111111111011000000001111 D7=0110000001101000100000110111
C8=1111111111101100000000111111 D8=1000000110100010000011011101
C9=1111111111011000000001111111 D9=0000001101000100000110111011
C10=1111111101100000000111111111 D10=0000110100010000011011101100
C11=1111110110000000011111111111 D11=0011010001000001101110110000
C12=1111011000000001111111111111 D12=1101000100000110111011000000
C13=1101100000000111111111111111 D13=0100010000011011101100000011
C14=0110000000011111111111111111 D14=0001000001101110110000001101
C15=1000000001111111111111111101 D15=0100000110111011000000110100
C16=0000000011111111111111111011 D16=1000001101110110000001101000
解密过程与加密过程相反,所得的数据的顺序恰好相反。在此就不赘述。
参考书目:
《计算机系统安全》 重庆出版社 卢开澄等编着
《计算机密码应用基础》 科学出版社 朱文余等编着
《Visual C++ 6.0 编程实例与技巧》 机械工业出版社 王华等编着
❻ DES算法加密的算法步骤是
#define READFILESIZE 512
步骤:
1.从文件中读取READFILESIZE个字节的数据
2.,如果从文件中读出的数据少于READFILESIZE个,以0补足,然后根据用户指定的类型对这READFILESIZE个字节的数据进行操作.
3.判断文件是否结束,没有则执行步骤1
4.把加密后的文件实际长度添加到密文的末尾
5.结束
采用一次只从文件读取READFILESIZE个字节是在为了防止由于需要加密或解密的文件太大导致内存不够的情况出现。
❼ DES算法加密后长度比原文增长多少! 跪求高手解答
不变的,64位加密之后还是变成64位进行下一轮加密,总之加密之前和加密之后长度是不变的
❽ 当待加密明文长度为任意长时,如何使用DES算法来进行加密呢
不知道你用什么语言,下面是C#的写法。在C#里使用对称加密不考虑明文大小,因为明文被处理成流.
public class TestClass
{
static void Main(string[] args)
{
byte[] key = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };
byte[] iv = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };
byte[] bytes = Encoding.UTF8.GetBytes("任意长度字符串");
byte[] enBytes = Encrypt(bytes, key, iv);
}
static byte[] Encrypt(byte[] bytes, byte[] key, byte[] iv)
{
MemoryStream ms = new MemoryStream();
DESCryptoServiceProvider desCsp = new DESCryptoServiceProvider();
desCsp.BlockSize = iv.Length * 8;
CryptoStream cs = new CryptoStream(ms, desCsp.CreateEncryptor(key, iv), CryptoStreamMode.Write);
cs.Write(bytes, 0, bytes.Length);
cs.FlushFinalBlock();
cs.Close();
desCsp.Clear();
return ms.ToArray();
}
}
❾ 怎么用des算法对文件进行加密
这个我不会
给文件加密,我使用的是超级加密3000.
超级加密3000有超快和最强的文件、文件夹加密功能、数据保护功能,文件夹、文件的粉碎删除以及文件夹伪装等功能。
❿ 推导DES加密算法原理
密码体制从原理上可分为2大类,即单钥密码体制和双钥密码体制。
单钥密码体制是指信息的发送方和接受方共享一把钥匙。在现代网络通信条件下,该 体制的一个关键问题是如何将密钥安全可靠地分配给通信的对方,并进行密钥管理。因此单 钥密码体制在实际应用中除了要设计出满足安全性要求的加密算法外,还必须解决好密码的 产生、分配、传输、存储和销毁等多方面问题。单钥密码可分为古典密码、流密码和分组密 码,DES就属于分组密码中的一种。
双钥密码体制又称公钥密码体制,其最大特点是采用2个密钥将加密、解密分开。在 双钥体制下,每个用户都拥有2把密钥,—个公开,一个自己专用。当使用用户专用密钥加 密,而用该用户公开密钥解密时,则可实现一个被加密的消息能被多个用户解读;当使用 用户公开密钥加密,而用该用户专用密钥解密时,则可实现传输的信息只被一个用户解读。 前者常被用于数字签名,后者常被用于保密通信。
DES算法详述
DES算法把64位的明文输入块变为64位的密文输出块,他所使用的密钥也是64位,DES对64 位的明文分组进行操作。通过一个初始置换,将明文分组分成左半部分和右半部分,各32位 长。然后进行16轮相同的运算,这些相同的运算被称为函数f,在运算过程中数据和密 钥相结合。经过16轮运算后左、右部分在一起经过一个置换(初始置换的逆置换),这样算 法就完成了。