您好,欢迎来到百家汽车网。
搜索
您的当前位置:首页DES算法实验报告

DES算法实验报告

来源:百家汽车网

学号:姓名:年级:专业:

DES密码的实现

一、DES算法介绍

DES算法为密码中的对称密码,又被称为美国数据加密标准,是19__年公司研制的对称密码加密算法。明文按位进行分组,密钥长位,密钥事实上是56位参与DES运算。它将位输入经过一系列变换得到位的输出。

图1表示了DES加密的整个机制。对于任意加密方案,总有两个输入,明文和密钥。DES的明文长位,密钥长56位。从图中左半部分,可见明文的处理经过了三个阶段。首先,位的明文经过初始置换(IP)而被重新排列。然后进行16轮相同函数作用,每轮作用都有置换和代替。最后一轮的输出有位,它是输入明文和密钥的函数。其左半部分和右半部分互换产生预输出。最后预输出再被与初始置换(IP)互逆的置换(IP-1)产生位的密文。

右半部分给出了使用56位密钥的过程。首先,密钥经过了一个置换后,再经过循环左移和一个置换分别得到各轮字谜要Ki用于各轮的迭代。每轮的置换函数都是一样的,但是由于密钥的循环和移位使得各轮子密钥互不相同。

图2给出了一轮变换的内部结构。首先,左半部分,位中间数据的左右两部分作为的32位数据,分别记为L和R。在经典的Feistel密码中,每轮变换的整个过程可以写为下面公式:

Li=Ri-1

Ri=Li-1F(Ri-1,Ki)

轮密钥Ki长度为48位,R是32位。首先将R拓展成48位,其中有16位是重复的。这48位与Ki异或,所得结果再用一个代替函数作用产生32位输出,再用一个置换表置换后输出。

二、DES算法源代码及运行结果

/程序的输入输出都是16位十六进制的数/

include"stdio.h"

change函数:将每位十六进制转换为二进制数

voidchange(inta,intN[4])

inti,b;

i=3;

while(a!=0)

b=a%2;

a=a/2;

N[i]=b;

i--;

if(i>=0)

while(i>=0)

N[i--]=0;

ipbiao函数:构造位的ip置换表voidipbiao(intip[8][8])

longi,j,k;

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

i=2+j2;

for(k=7;k>=0;k--)

ip[j][k]=i;

i+=8;

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

i=1+(j-4)2;

for(k=7;k>=0;k--)

ip[j][k]=i;

i+=8;

IPRevFun函数:构造逆初始置换表

voidIPRevFun(intL[32],intR[32],intre[]){

inti,j;

inttem[];

intip11[]={40,8,48,16,56,24,,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};j=0;

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

tem[j++]=L[i];

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

tem[j++]=R[i];

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

re[i]=tem[ip11[i]-1];

PUTIN函数:请用户输入明文voidPUTIN(intmw[8][8])

charM[16];

intnum[4];

inti,s,j,n,h,l;

n=0;

printf("请输入16位十六进制数:");for(i=0;i<16;i++)

scanf("%c",M[i]);

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

if(M[i]<60)

s=M[i]-48;

elseif(M[i]<90)

s=M[i]-55;

else

s=M[i]-87;

change(s,num);

if(4(n+1)%8==0)

h=4(n+1)/8-1;

else

h=4(n+1)/8;

if((n+1)%2==0)

l=4;

else

l=0;

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

mw[h][l++]=num[j];}

InitRep函数:将明文按ip表重新排列

voidInitRep(intmw[8][8],inttem[8][8])

inti,j,h,l,a;

intip[8][8];

ipbiao(ip);

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

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

a=ip[i][j];

if(a%8==0)

h=a/8-1;

l=7;

else

h=a/8;

l=a%8-1;

tem[i][j]=mw[h][l];

BreakLR函数:将位明文分为两个32位,分别为L和RvoidBreakLR(inttem[8][8],intL[32],intR[32]){

inth,l,i;

i=0;

for(h=0;h<4;h++)

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

L[i++]=tem[h][l];

i=0;

for(h=4;h<8;h++)

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

R[i++]=tem[h][l];

XXX函数:将R的32位明文变为48位

voidXXX(intr[32],intE[8][6])

inti,h,l;

i=0;

while(i<32)

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

for(l=1;l<5;l++)

E[h][l]=r[i++];

E[0][0]=r[31];

E[0][5]=r[4];

i=9;

for(h=1;h<7;h++)

E[h][0]=r[4h-1];

E[h][5]=r[i-1];

i=i+4;

E[7][0]=r[27];

E[7][5]=r[0];

KeyProd函数:将68位密钥通过左移和置换/压缩(置换选择2)压缩成48位voidKeyProd(intmw[8][8],intn,intkey[48])

inta,i,h,l,j,N,tem,hm,lm,t;

intd[28];

intkt[56];

intc[28];

intk[56];

intls[17]={0,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

intip1[8][7]={{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}};intpc2[48]={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};

i=0;

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

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

a=ip1[h][l];

if(a%8==0)

hm=a/8-1;

lm=7;

else

hm=a/8;lm=a%8-1;}

kt[i++]=mw[hm][lm];}

j=0;

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

c[j++]=kt[i];

t=0;

for(i=28;i<56;i++)

d[t++]=kt[i];

N=0;

for(i=1;i<=n;i++)

N+=ls[i];

while(N)

tem=c[0];

for(i=1;i<28;i++)c[i-1]=c[i];c[27]=tem;

N--;

N=0;

for(i=1;i<=n;i++)

N+=ls[i];

while(N)

tem=d[0];

for(i=1;i<28;i++)d[i-1]=d[i];d[27]=tem;

N--;

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

k[i]=c[i];

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

k[i++]=d[j];

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

key[i]=k[pc2[i]-1];}

_orFun函数:48位明X与48位密钥的异或运算

void_orFun(intE[8][6],intk[48],intr[48])

inth,l,a;

a=0;

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

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

if(E[h][l]!=k[a])

r[a++]=1;

else

r[a++]=0;

LP_orFun函数:参数为两个一维数组的异或函数voidLP_orFun(intpout[32],intlr[32],intre[32]){

inti;

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

if(pout[i]==lr[i])

re[i]=0;

else

re[i]=1;

FSPFun函数:每一轮迭代过程F函数中的置换(P)voidFSPFun(intp[32],intpout[32])

inti;

intsp[32]={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};

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

pout[i]=p[sp[i]-1];

FeiSFun函数:每一轮F函数中的代替/选择(S盒)voidFeiSFun(intk[48],intp[32])

inti,ni,pi,h,l,sh,sl,out;

intnum[4];

intsi[8][6];

ints[8][]={{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},{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},{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},{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},{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},{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},{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},{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}};pi=0;

i=0;

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

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

si[h][l]=k[i++];

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

sh=2si[h][0]+si[h][5];

sl=8si[h][1]+4si[h][2]+2si[h][3]+si[h][4];

out=s[h][sh16+sl];

change(out,num);

for(ni=0;ni<4;ni++)

p[pi++]=num[ni];

ArrayCopy函数:将一个数组的值直接复制到另一个数组voidArrayCopy(inta[32],intb[32])

inti;

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

a[i]=b[i];

Feistel函数

voidFeistel(intr[32],intk[48],intpo[32])

intE_[8][6];

intpi[32];

intre[48];

E_tension(r,E_);

_orFun(E_,k,re);

FeiSFun(re,pi);

FSPFun(pi,po);

BtoO_函数:将二进制数转化为十六进制

voidBtoO_(inta[],charb[16])

inti,j,k,n,r;

n=0;

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

k=8;

r=0;

for(j=1;j<5;j++)

r+=a[n]k;

k=k/2;

n++;

if(r<10)

b[i]=r+48;

else

b[i]=r+55;

主函数

voidmain()

inti,d;

intms[8][8];

intmw[8][8];

inttem[8][8];

intkey[48];

charres[16];

intrr[32];

intR1[32];

intresult[];

intL[32];

intR[32];

printf("--------------------欢迎使用DES加密-------------------- ");printf("------------------请输入要加密的明文------------------- ");PUTIN(mw);

getchar();

printf("----------------------请输入密匙----------------------- ");PUTIN(ms);

InitRep(mw,tem);

BreakLR(tem,L,R);

for(d=1;d<16;d++)

KeyProd(ms,d,key);

Feistel(R,key,rr);

LP_orFun(rr,L,R1);

ArrayCopy(L,R);

ArrayCopy(R,R1);

KeyProd(ms,16,key);

Feistel(R,key,rr);

LP_orFun(rr,L,R1);

ArrayCopy(L,R1);

IPRevFun(L,R,result);

BtoO_(result,res);

printf("---------------------加密后的密文为-------------------- ");

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

printf("%2c",res[i]);

if((i+1)%4==0)

printf(" ");

运行结果:

三、实验心得

随着计算机处理能力的提高,只有56位密钥长度的DES算法不再被认为是安全的,但是认识DES算法还是很有必要的,通过学习DES算法可以更好的了解它的代替者——3DES,而且DES算是对称密码中的一个经典。

通过两周的DES编程让我更加深入的理解了这一算法,编程过程是枯燥的,常常会出现错误,打击自我,但是最后还是克服困难成功的完成了本次实验。这次实验也使我懂得了理论与实际相结合是很非常重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,在实践中深化对理论的理解。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- baijiahaobaidu.com 版权所有 湘ICP备2023023988号-9

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务