密码学实验实验5 Hash算法.docx

上传人:b****6 文档编号:4543367 上传时间:2022-12-06 格式:DOCX 页数:40 大小:309.58KB
下载 相关 举报
密码学实验实验5 Hash算法.docx_第1页
第1页 / 共40页
密码学实验实验5 Hash算法.docx_第2页
第2页 / 共40页
密码学实验实验5 Hash算法.docx_第3页
第3页 / 共40页
密码学实验实验5 Hash算法.docx_第4页
第4页 / 共40页
密码学实验实验5 Hash算法.docx_第5页
第5页 / 共40页
点击查看更多>>
下载资源
资源描述

密码学实验实验5 Hash算法.docx

《密码学实验实验5 Hash算法.docx》由会员分享,可在线阅读,更多相关《密码学实验实验5 Hash算法.docx(40页珍藏版)》请在冰豆网上搜索。

密码学实验实验5 Hash算法.docx

密码学实验实验5Hash算法

实验报告

一、实验目的

1.MD5算法

(1)理解Hash函数的计算原理和特点

(2)理解MD5算法原理

2.SHA1算法

(1)理解SHA1函数的计算原理和特点

(2)理解SHA1算法原理

二、实验内容与设计思想

①MD5算法

 MD5哈希算法流程:

1.对于任意长度的明文,MD5首先对其进行分组,使得每一组的长度为512位,然后对这些明文分组反复重复处理。

对于每个明文分组的摘要生成过程如下:

(1)将512位的明文分组划分为16个子明文分组,每个子明文分组为32位。

(2)申请4个32位的链接变量,记为A、B、C、D。

(3)子明文分组与链接变量进行第1轮运算。

(4)子明文分组与链接变量进行第2轮运算。

(5)子明文分组与链接变量进行第3轮运算。

(6)子明文分组与链接变量进行第4轮运算。

(7)链接变量与初始链接变量进行求和运算。

(8)链接变量作为下一个明文分组的输入重复进行以上操作。

(9)最后,4个链接变量里面的数据就是MD5摘要。

2.MD5分组过程

对于任意长度的明文,MD5可以产生128位的摘要。

任意长度的明文首先需要添加位数,使明文总长度为448(mod512)位。

在明文后添加位的方法是第一个添加位是l,其余都是0。

然后将真正明文的长度(没有添加位以前的明文长度)以64位表示,附加于前面已添加过位的明文后,此时的明文长度正好是512位的倍数。

当明文长度大于2的64次方时,仅仅使用低64位比特填充,附加到最后一个分组的末尾。

经过添加处理的明文,其长度正好为512位的整数倍,然后按512位的长度进行分组(block),可以划分成L份明文分组,我们用Y0,Y1,……,YL-1表示这些明文分组。

对于每一个明文分组,都要重复反复的处理,如图所示。

3.MD5子明文分组和链接变量

对于512位的明文分组,MD5将其再分成16份子明文分组(sub-block),每份子明文分组为32位,我们使用M[k](k=0,1,……15)来表示这16份子明文分组。

这里的概念要弄清楚,一个添加位后的明文可以划分为L份明文分组,而一个明文分组又可以划分为16份子明文分组。

MD5有4轮非常相似的运算,每一轮包括16个类似的步骤,每一个步骤的数据处理都是针对4个32位记录单元中的数据进行的。

这4个32位记录单元称为“链接变量”,分别标记为A、B、C、D。

这4个链接变量的初始值以16进位制表示如下(低字节优先)A:

0x01234567,B:

0x89ABCDEF,C:

0xFEDCBA98,D:

0x76543210,这时A、B、C、D四个链接变量的值为:

A=0x67452301,B=0xEFCDAB89,C=0x98BADCFE,D=0x10325476。

链接变量用于存放中间散列函数值,经过4轮运算(共64个步骤)之后,链接变量A,B,C,D中的128位即为中间散列函数值。

中间散列函数值作为下一个明文分组的输入继续使用,当所有的明文分组都处理完毕后,链接变量A,B,C,D中的128位数据就是摘要。

4.MD5第1轮运算

MD5有4轮非常相似的运算,每一轮包括16个类似的步骤,当第1轮运算中的第1步骤开始处理时,A、B、C、D四个链接变量中的值先赋值到另外4个记录单元A′,B′,C′,D′中。

这4个值将保留,用于在第4轮的最后一个步骤完成之后与A,B,C,D进行求和操作。

第1轮的操作程序为FF(a,b,c,d,M[k],S,T[i])

它表示的逻辑为:

a←b+((a+F(b,c,d)+M[k]+T[i])<<

其中,a、b、c、d为32位的变量,M[k]表示相应的子明文分组,对于4轮共64步的MD5算法中T[i]是64个不同的固定的数值,S为循环左移的位数,F(x,y,z)是第一轮的逻辑函数,最后将结果存放在链接变量A中,固定值T[i],循环左移位数和逻辑函数将在以后讨论。

 第1轮16步的固定值T[i]的取值如表所示。

MD5第1轮固定数T

T[1]=D76AA478

T[5]=F57C0FAF

T[9]=698098D8

T[13]=6B901122

T[2]=E8C7B756

T[6]=4787C62A

T[10]=8B44F7AF

T[14]=FD987193

T[3]=242070DB

T[7]=A8304613

T[11]=FFFF5BB1

T[15]=A679438E

T[4]=C1BDCEEE

T[8]=FD469501

T[12]=895CD7BE

T[16]=49B40821

 MD5规定,第一轮的16步的操作程序如表所示。

MD5第1轮16步运算

步骤数

运算

1

FF(A,B,C,D,M[0],7,0xD76AA478)

2

FF(D,A,B,C,M[1],12,0xE8C7B756)

3

FF(C,D,A,B,M[2],17,0x242070DB)

4

FF(B,C,D,A,M[3],22,0xC1BDCEEE)

5

FF(A,B,C,D,M[4],7,0xF57C0FAF)

6

FF(D,A,B,C,M[5],12,0x4787C62A)

7

FF(C,D,A,B,M[6],17,0xA8304613)

8

FF(B,C,D,A,M[7],22,0xFD469501)

9

FF(A,B,C,D,M[8],7,0x698098D8)

10

FF(D,A,B,C,M[9],12,0x8B44F7AF)

11

FF(C,D,A,B,M[10],17,0xFFFF5BB1)

12

FF(B,C,D,A,M[11],22,0x895CD7BE)

13

FF(A,B,C,D,M[12],7,0x6B901122)

14

FF(D,A,B,C,M[13],12,0xFD987193)

15

FF(C,D,A,B,M[14],17,0xA6794383)

16

FF(B,C,D,A,M[15],22,0x49B40821)

  MD5算法中,第一轮的逻辑函数为F(x,y,z)=(x& y)|(~x&z),MD5的算法比较复杂,每一轮包括16步类似的运算,下面我们以第1轮的第1步和第2步为例来展示每一步的运算。

例如,子明文分组M[0]=0x4368696E,第1轮的操作程序为FF(a,b,c,d,M[k],S,T[i]),它表示的逻辑为:

a←b+((a+F(b,c,d)+M[k]+T[i])<<

第一轮的逻辑函数F(x,y,z)=(x&y)|(~x&z),由表8-1-2知,第1轮第1步的运算为:

FF(A,B,C,D,M[0],7,0xD76AA478),注意到这里的0xD76AA478就是T[1]的值,变量a、b、c、d分别代表链接变量A、B、C、D。

首先,b、c、d要经过逻辑函数F,即:

 然后得到的值要与A、M[0]和T[1]相加得0x67452301+0x98BADCFE+0x6E696843+0xD76AA478=0x45D40CBA,0x45D40CBA要循环左移7位,得到结果:

0xEA065D22,0xEA065D22与b相加得:

0xEA065D22+0xEFCDAB89=0xD9D408AB,最后,将这个结果赋值给a,第1步的计算就完成了,只有链接变量A发生了改变,这时链接标量的值为:

   A=0xD9D408AB

   B=0x89ABCDEF

   C=0xFEDCBA98

   D=0x76543210

经过16个步骤之后,MD5的第一轮运算就完成了,链接变量A、B、C、D将携带第1轮运算后的数值进入第二轮运算。

5.MD5后3轮运算

MD5第2轮、第3轮和第4轮算运与第一轮运算相似,这里给出相应的操作程序、固定数T、每一步运算和逻辑函数。

   第2轮的逻辑函数为:

G(x,y,z)=(x&z)|(y&~z)。

   第3轮的逻辑函数为:

H(x,y,z)=x⊕y⊕z。

   第4轮的逻辑函数为:

I(x,y,z)=y⊕(x&~z)。

   第2轮的操作程序为:

GG(A,B,C,D,M[k],S,T[i])。

   它表示的逻辑为:

a←b+((a+G(B,C,D)+M[k]+T[i])<<

   第3轮的操作程序为:

HH(A,B,C,D,M[k],S,T[i])。

   它表示的逻辑为:

a←b+((a+H(B,C,D)+M[k]+T[i])<<

   第4轮的操作程序为:

II(A,B,C,D,M[k],S,T[i])。

   它表示的逻辑为:

a←b+((a+I(B,C,D)+M[k]+T[i])<<

后3轮的固定数T[i]

T[17]=F61E2562

T[33]=FFFA3942

T[49]=F4292244

T[18]=C040B340

T[34]=8771F681

T[50]=432AFF97

T[19]=265E5A51

T[35]=699D6122

T[51]=AB9423A7

T[20]=E9B6C7AA

T[36]=FDE5380C

T[52]=FC93A039

T[21]=D62F105D

T[37]=A4BEEA44

T[53]=655B59C3

T[22]=02441453

T[38]=4BDECFA9

T[54]=8F0CCC92

T[23]=D8A1E681

T[39]=F6BB4B60

T[55]=FFEFF47D

T[24]=E7D3FBC8

T[40]=BEBFBC70

T[56]=85845DD1

T[25]=21E1CDE6

T[41]=289B7EC6

T[57]=6FA87E4F

T[26]=C33707D6

T[42]=EAA127FA

T[58]=FE2CE6E0

T[27]=F4D50D87

T[43]=D4EF3085

T[59]=A3014314

T[28]=455A14ED

T[44]=04881D05

T[60]=4E0811A1

T[29]=A9E3E905

T[45]=D9D4D039

T[61]=F7657E82

T[30]=FCEEA3F8

T[46]=E6DB99E5

T[62]=BD3AF235

T[31]=676F02D9

T[47]=1FA27CF8

T[63]=2AD7D2BB

T[32]=8D2A4C8A

T[48]=C4AC5665

T[64]=EB86D391

6.求和运算

第四轮最后一步骤的A,B,C,D输出,将分别与A′,B′,C′,D′记录单元中数值进行求和操作。

其结果将成为处理下一个512位明文分组时记录单元A,B,C,D的初始值。

当完成了最后一个明文分组运算时,A,B,C,D中的数值就是最后的散列函数值。

②SHA1算法

SHA1哈希算法流程:

1.对于任意长度的明文,SHA1首先对其进行分组,使得每一组的长度为512位,然后对这些明文分组反复重复处理。

对于每个明文分组的摘要生成过程如下:

(1)将512位的明文分组划分为16个子明文分组,每个子明文分组为32位。

(2)申请5个32位的链接变量,记为A、B、C、D、E。

(3)16份子明文分组扩展为80份。

(4)80份子明文分组进行4轮运算。

(5)链接变量与初始链接变量进行求和运算。

(6)链接变量作为下一个明文分组的输入重复进行以上操作。

(7)最后,5个链接变量里面的数据就是SHA1摘要。

2.SHA1的分组过程

对于任意长度的明文,SHA1的明文分组过程与MD5相类似,首先需要对明文添加位数,使明文总长度为448(mod512)位。

在明文后添加位的方法是第一个添加位是l,其余都是0。

然后将真正明文的长度(没有添加位以前的明文长度)以64位表示,附加于前面已添加过位的明文后,此时的明文长度正好是512位的倍数。

与MD5不同的是SHA1的原始报文长度不能超过2的64次方,另外SHA1的明文长度从低位开始填充。

经过添加位数处理的明文,其长度正好为512位的整数倍,然后按512位的长度进行分组(block),可以划分成L份明文分组,我们用Y0,Y1,……YL-1表示这些明文分组。

对于每一个明文分组,都要重复反复的处理,这些与MD5是相同的。

对于512位的明文分组,SHA1将其再分成16份子明文分组(sub-block),每份子明文分组为32位,我们使用M[k](k=0,1,……15)来表示这16份子明文分组。

之后还要将这16份子明文分组扩充到80份子明文分组,我们记为W[k](k=0,1,……79),扩充的方法如下。

   Wt=Mt,当0≤t≤15

   Wt=(Wt-3⊕Wt-8⊕Wt-14⊕Wt-16)<<<1,当16≤t≤79

SHA1有4轮运算,每一轮包括20个步骤(一共80步),最后产生160位摘要,这160位摘要存放在5个32位的链接变量中,分别标记为A、B、C、D、E。

这5个链接变量的初始值以16进制位表示如下。

   A=0x67452301

   B=0xEFCDAB89

   C=0x98BADCFE

   D=0x10325476

   E=0xC3D2E1F0

3.SHA1的4轮运算

SHA1有4轮运算,每一轮包括20个步骤,一共80步,当第1轮运算中的第1步骤开始处理时,A、B、C、D、E五个链接变量中的值先赋值到另外5个记录单元A′,B′,C′,D′,E′中。

这5个值将保留,用于在第4轮的最后一个步骤完成之后与链接变量A,B,C,D,E进行求和操作。

SHA1的4轮运算,共80个步骤使用同一个操作程序,如下:

   A,B,C,D,E←[(A<<<5)+ft(B,D,C)+E+Wt+Kt],A,(B<<<30),C,D

其中ft(B,D,C)为逻辑函数,Wt为子明文分组W[t],Kt为固定常数。

这个操作程序的意义为:

   ● 将[(A<<<5)+ft(B,D,C)+E+Wt+Kt]的结果赋值给链接变量A;

   ● 将链接变量A初始值赋值给链接变量B;

   ● 将链接变量B初始值循环左移30位赋值给链接变量C;

   ● 将链接变量C初始值赋值给链接变量D;

   ● 将链接变量D初始值赋值给链接变量E。

SHA1规定4轮运算的逻辑函数如表所示。

SHA1的逻辑函数

步骤

函数定义

步骤

函数定义

1

0≤t≤19

ft(B,C,D)=(B·C)V(~B·D)

3

40≤t≤59

 ft(B,C,D)=(B·C)V(B·D)V(C·D)

2

20≤t≤39

ft(B,C,D)=B⊕C⊕D

4

60≤t≤79

ft(B,C,D)=B⊕C⊕D

   

在操作程序中需要使用固定常数Ki(i=0,1,2,……79),Ki的取值如表所示:

SHA1的常数K取值表

步骤

函数定义

步骤

函数定义

1

0≤t≤19

Kt=5A827999

3

40≤t≤59

Kt=8F188CDC

2

20≤t≤39

Kt=6ED9EBA1

4

60≤t≤79

Kt=CA62C1D6

   

我们同样举一个例子来说明SHA1哈希算法中的每一步是怎样进行的,比起MD5算法,SHA1相对简单,假设W[1]=0x12345678,此时链接变量的值分别为A=0x67452301、B=0xEFCDAB89、C=0x98BADCFE、D=0x10325476、E=0xC3D2E1F0,那么第1轮第1步的运算过程如下。

(1)将链接变量A循环左移5位,得到的结果为:

0xE8A4602C。

(2)B,C,D经过相应的逻辑函数:

(3)将第

(1)步,第

(2)步的结果与E,W[1],和K[1]相加得:

(4)将B循环左移30位得:

(B<<<30)=0x7BF36AE2。

(5)将第3步结果赋值给A,A(这里是指A的原始值)赋值给B,步骤4的结果赋值给C,C的原始值赋值给D,D的原始值赋值给E。

(6)最后得到第1轮第1步的结果:

   A=0xB1E8EF2B

B=0x67452301

C=0x7BF36AE2

D=0x98BADCFE

E=0x10325476

按照这种方法,将80个步骤进行完毕。

第四轮最后一个步骤的A,B,C,D,E输出,将分别与记录单元A′,B′,C′,D′,E′中的数值求和运算。

其结果将作为输入成为下一个512位明文分组的链接变量A,B,C,D,E,当最后一个明文分组计算完成以后,A,B,C,D,E中的数据就是最后散列函数值。

三、实验步骤和调试过程(建议画出程序流程图)

1.MD5算法实验步骤:

(1)编码实现MD5算法,源代码如下:

#include

#include

#include

#include

#include

#include

#include

#include

usingnamespacestd;

classMD5

{

public:

MD5();//DES:

默认构造函数

stringhash(stringinput,stringinmode,stringoutmode);//hash:

进行MD5Hash,返回MD5Hash结果

private:

unsignedint__plain,__enpt;//__plain:

原始消息;__enpt:

MD5Hash结果

stringhexToBinary(stringinput);//hexToBinary:

十六进制输入转换为二进制

stringbinToHexto(stringinput);//binToHexto:

二进制输入转换为十六进制

voidprint(unsignedintinput);//print:

将unsignedint类型以32位二进制的形式输出

stringconvert(unsignedintinput);//convert:

将unsignedint类型以32位二进制的形式字符串转化

stringfillString(stringinput);//fillString:

对原始输入的二进制序列进行填充,填充到长度size符合size%512==448,然后附加一个64位的填充前长度值序列

voidinitDepart(stringinput,vector&output);//initDepart:

该方法将N*512位的二进制字符串拆分为若干512位的字符串数组

voiddepartString(stringinput,unsignedintoutput[16]);//departString:

将512位的二进制序列输入拆分为16个32位二进制的unsignedint类型x序列

unsignedintcycleLeftShift(unsignedinta,unsignedintb);//cycleLeftShift:

实现循环左移

unsignedintF(unsignedintx,unsignedinty,unsignedintz);//F:

非线性函数F

unsignedintG(unsignedintx,unsignedinty,unsignedintz);//G:

非线性函数G

unsignedintH(unsignedintx,unsignedinty,unsignedintz);//H:

非线性函数H

unsignedintI(unsignedintx,unsignedinty,unsignedintz);//I:

非线性函数I

unsignedintFF(unsignedint&a,unsignedintb,unsignedintc,unsignedintd,unsignedintMj,unsignedints,unsignedintti);//FF:

复合操作函数FF

unsignedintGG(unsignedint&a,unsignedintb,unsignedintc,unsignedintd,unsignedintMj,unsignedints,unsignedintti);//GG:

复合操作函数GG

unsignedintHH(unsignedint&a,unsignedintb,unsignedintc,unsignedintd,unsignedintMj,unsignedints,unsignedintti);//HH:

复合操作函数HH

unsignedintII(unsignedint&a,unsignedintb,unsignedintc,unsignedintd,unsignedintMj,unsignedints,unsignedintti);//HH:

复合操作函数II

string_MD5(stringuser_input);//_MD5:

MD5Hash底层实现函数

};

/*********************publicfunctions*************************/

/*0.

*MD5:

类默认初始化函数

*/

MD5:

:

MD5()

{

}

/*2.

*hash:

该方法进行MD5Hash,返回MD5Hash结果

*Param:

input--无前缀十六进制或者二进制原始信息输入,inmode--'0b'指示以二进制形式输入,'0x'指示以十六进制形式输入,outmode--'0b'指示以二进制形式输出,'0x'指示以十六进制形式输出

*Return:

无前缀十六进制或者二进制Hash结果输出

*/

stringMD5:

:

hash(stringinput,stringinmode,stringoutmode)

{

input=(inmode=="0x")?

hexToBinary(input):

input;

stringres=_MD5(input);

res=(outmode=="0x")?

binToHexto(res):

res;

returnres;

}

 

/*********************privatefunctions************************/

/*1.

*hexToBinary:

该方法将十六进制字符串转化为二进制字符串(均不含前缀)

*Param:

input--无前缀十六进制输入

*Return:

output--无前缀二进

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1