MD5算法的设计与实现

合集下载

实验三 MD5算法的设计与实现

实验三 MD5算法的设计与实现

实验三MD5算法的设计与实现MD5算法及C++实现一、理论部分:1、预备知识1.1什么是数据校验通俗的说,就是为保证数据的完整性,用一种指定的算法对原始数据计算出的一个校验值。

接收方用同样的算法计算一次校验值,如果和随数据提供的校验值一样,就说明数据是完整的。

1.2最简单的检验实现方法:最简单的校验就是把原始数据和待比较数据直接进行比较,看是否完全一样这种方法是最安全最准确的。

同时也是效率最低的。

适用范围:简单的数据量极小的通讯。

应用例子:龙珠cpu在线调试工具bbug.exe。

它和龙珠cpu间通讯时,bbug发送一个字节cpu返回收到的字节,bbug确认是刚才发送字节后才继续发送下一个字节的。

1.3奇偶校验Parity Check实现方法:在数据存储和传输中,字节中额外增加一个比特位,用来检验错误。

校验位可以通过数据位异或计算出来。

应用例子:单片机串口通讯有一模式就是8位数据通讯,另加第9位用于放校验值。

1.4 bcc异或校验法(block check character)实现方法:很多基于串口的通讯都用这种既简单又相当准确的方法。

它就是把所有数据都和一个指定的初始值(通常是0)异或一次,最后的结果就是校验值,通常把她附在通讯数据的最后一起发送出去。

接收方收到数据后自己也计算一次异或和校验值,如果和收到的校验值一致就说明收到的数据是完整的。

校验值计算的代码类似于:unsigned uCRC=0;//校验初始值for(int i=0;i<DataLenth;i++) uCRC^=Data[i];适用范围:适用于大多数要求不高的数据通讯。

应用例子:ic卡接口通讯、很多单片机系统的串口通讯都使用。

1.5 crc循环冗余校验(Cyclic Redundancy Check)实现方法:这是利用除法及余数的原理来进行错误检测的.将接收到的码组进行除法运算,如果除尽,则说明传输无误;如果未除尽,则表明传输出现差错。

MD5算法的原理与实现

MD5算法的原理与实现

MD5算法的原理与实现***********************************************声明************************************************原创作品,出⾃ “晓风残⽉xj” 博客,欢迎转载。

转载时请务必注明出处()。

因为各种原因。

可能存在诸多不⾜。

欢迎斧正!*****************************************************************************************************⼀、MD5概念MD5,全名Message Digest Algorithm 5 ,中⽂名为消息摘要算法第五版,为计算机安全领域⼴泛使⽤的⼀种散列函数,⽤以提供消息的完整性保护。

上⾯这段话话引⽤⾃百度百科。

我的理解MD5是⼀种信息摘要算法,主要是通过特定的hash散列⽅法将⽂本信息转换成简短的信息摘要,压缩+加密+hash算法的结合体,是绝对不可逆的。

⼆、MD5计算步骤MD5以512位分组来处理输⼊的信息。

且每⼀分组⼜被划分为16个32位⼦分组。

经过了⼀系列的处理后。

算法的输出由四个32位分组组成,将这四个32位分组级联后将⽣成⼀个128位散列值。

第⼀步、填充假设输⼊信息的长度(bit)对512求余的结果不等于448,就须要填充使得对512求余的结果等于448。

填充的⽅法是填充⼀个1和n个0。

填充完后,信息的长度就为N*512+448(bit)。

第⼆步、记录信息长度⽤64位来存储填充前信息长度。

这64位加在第⼀步结果的后⾯,这样信息长度就变为N*512+448+64=(N+1)*512位。

第三步、装⼊标准的幻数(四个整数)标准的幻数(物理顺序)是(A=(01234567)16,B=(89ABCDEF)16。

C=(FEDCBA98)16,D=(76543210)16)。

假设在程序中定义应该是(A=0X67452301L,B=0XEFCDAB89L。

毕业设计-md5算法的研究与实现数据存储加密—论文[管理资料]

毕业设计-md5算法的研究与实现数据存储加密—论文[管理资料]

毕业设计(论文)MD5算法的研究与实现------数据存储加密论文作者姓名:申请学位专业:申请学位类别:指导教师姓名(职称):论文提交日期:MD5算法的研究与实现------数据存储加密摘要随着网络技术的广泛应用,网络信息安全越来越引起人们的重视。

针对数据在存储的时候存在大量的安全问题,目前通常将需要存储的数据进行加密然后再存储,应用MD5算法是一个不错的选择。

MD5算法的全称是Message-Digest algorithm 5,是一种用于产生数字签名的单项散列算法。

它的作用是让大容量信息在用数字签名软件签署私人密钥前被“压缩”成一种保密的格式,即将一个任意长度的“字节串”通过一个不可逆的字符串变换算法变换成一个128bit的串。

该毕业设计是运用microsoft visual c++ ,主要是通过算法实现数据的加密存储。

文章分成五部分。

第一,二部分描述了MD5的目前现状和相关理论知识,也让我们了解MD5的定义。

重点是MD5的流程实现和封装DLL。

在MD5算法的DLL 封装这章,主要是描述我们为什么要选用封装DLL的原因,以及封装的好处。

设计流程这一部分里包含读取,修改,插入,删除这几个功能的实现情况,并用流程图的方式来分别描述了这四大功能模块的实现过程。

最后一部分显示了系统测试的内容和系统主要功能运行界面图。

关键词:信息安全;MD5;加密;封装The Research and Implementation for MD5 Algorithm-------- Data Storage and EncryptionAbstractWith the wide application of the network technology, the information of the network safety causes people's attention more and more. A large number of security questions appear while storing data, the data that usually store needing at present are encrypted then stored, it is a good choice to use MD5 algorithm. The full name of MD5 algorithm is Message-Digest algorithm 5, is that a kind of individual event used for producing figures and signed breaks up and arranges algorithms. Its function is to let large capacity information " compress " and become a kind of secret form before signing the private key with the digital signature software, vary " byte bunch " of a wanton length into a great integer of one 128bit through an irreversible one bunch of algorithms of varying of character .Used Microsoft Visual C++ software and developed in this graduation project, is mainly to realize through the algorithm that the encryption of the data is stored. The article is divided into five parts. The first and second parts are describing the current situation and relevant theory knowledge at present of MD5, let us understand the definition of MD5. The focal point is the procedure of MD5 is realized and encapsulation to Dynamic Link Library. In this chapter of encapsulation MD5 class library to Dynamic Link Library, mainly describe why we will select encapsulation Dynamic Link Library for use , and the advantage of encapsulation . Design this of procedure and include reading in the part , revise , insert, delete the realization situations of these functions, and has described the realization course of this four major functions module respectively in way of the flow chart . The last part has shown that the content of system testing and main function of system operate the interface picture .Key words: information security; MD5; encrypt; Packaging目录论文总页数:23页1 引言 (1)研究现状 (1)选题意义 (2)选题背景 (2)2 相关理论基础 (3)单向散列函数 (3)单向散列函数的基本原理 (3)散列值的长度 (4)MD5算法的基本原理 (4)MD5的应用 (12)3 需求分析及设计方案 (14)主要功能模块 (14)数据加密 (14)数据存储 (14)数据库设计 (14)主要流程图 (15)4 MD5算法的DLL封装 (15)加载时动态链接 (16)运行时动态链接 (16)DLL封装情况 (16)5 具体设计流程及实现 (17)读取的设计和实现 (17)插入的设计和实现 (18)修改的设计和实现 (18)删除的设计和实现 (19)6 调试与分析 (19)概述 (19)测试分析报告 (20)结论 (20)参考文献 (21)致谢 (22)声明 (23)1引言随着网络通信技术和Internet的联系日益增强,出现了一系列与网络安全相关的问题:如对主机的攻击,网络上传输的信息被截取、篡改、重发等,由此,它对网络应用的进一步推广构成了巨大威胁,因此密码体制[1]就在这种背景下应运而生了。

MD5算法实验报告

MD5算法实验报告

MD5算法实验报告实验报告:MD5算法的原理与应用一、实验目的本实验旨在通过研究MD5(Message-Digest Algorithm 5)算法的原理和应用,了解其工作原理和实现过程,并掌握其具体应用技巧。

二、实验内容1.了解MD5算法的基本原理和特点;2.分析MD5算法的具体实现过程;3.实现一个简单的MD5加密程序,并进行测试;4.掌握MD5算法的应用技巧。

三、实验原理1. 输入任意长度的数据,输出固定长度的Hash值,通常为128位;2. 安全性较高,Hash值的变化能较好地反映原始数据的变化;3. 不可逆性:无法通过Hash值反推出原始数据;4. Hash值相同的概率很低,冲突概率较小。

1.数据填充:对输入数据进行填充,使其长度满足一定要求;2.划分数据:将填充后的数据划分为多个512位的数据块;3.初始化变量:设置四个32位的变量,作为初始值;4.处理数据块:对每个数据块进行处理,分为四轮,每轮包括四个步骤,即置换、模运算、加法和循环左移操作。

5. 输出结果:将四个32位变量连接起来,即得到最终的128位Hash值。

四、实验过程1.学习MD5算法的原理和实现细节;2. 使用Python编程语言实现一个简单的MD5加密程序,并进行测试。

实验代码如下:```import hashlibdef md5_encrypt(source):md5 = hashlib.md5md5.update(source.encode('utf-8'))return md5.hexdigestif __name__ == '__main__':source_str = input("请输入要加密的字符串:")encrypted_str = md5_encrypt(source_str)print("加密后的字符串为:", encrypted_str)```五、实验结果与分析通过上述实验代码,可以输入一个字符串,程序将会对该字符串进行MD5加密,并将加密结果输出。

MD5算法原理及其实现

MD5算法原理及其实现

MD5算法原理及其实现MD5(Message Digest Algorithm 5)是一种常用的哈希函数,它可以将输入数据通过一系列的计算步骤转换成固定长度的输出,通常为128位。

MD5算法是由美国密码学家、计算机安全专家罗纳德·李维斯特(Ronald Rivest)设计的,它在1992年成为了国际标准,常用于数据的完整性校验以及密码存储等应用场景。

1.填充消息:先将待处理的消息填充至长度为448(模512)的倍数,填充规则为在消息末尾添加一个1,然后添加若干个0,最后添加一个64位的原始消息长度。

这样可以确保消息的长度满足要求。

2.初始化缓冲区:将一个128位的缓冲区(A、B、C、D)初始化为特定的初始值(常数)。

3.消息分组:将填充后的消息分成若干个512位(16个32位字)的消息块。

4.处理消息块:对每个消息块进行相同的操作,操作包括四轮循环迭代(步骤5~8)。

5.轮函数1:将A、B、C、D的值作为输入,通过逻辑函数(与、或、非、异或)、非线性函数F以及循环左移操作,生成新的A、B、C、D的值。

6.轮函数2:将D、A、B、C的值作为输入,通过逻辑函数、非线性函数G以及循环左移操作,生成新的D、A、B、C的值。

7.轮函数3:将C、D、A、B的值作为输入,通过逻辑函数、非线性函数H以及循环左移操作,生成新的C、D、A、B的值。

8.轮函数4:将B、C、D、A的值作为输入,通过逻辑函数、非线性函数I以及循环左移操作,生成新的B、C、D、A的值。

9.更新缓冲区:将处理完的消息块的结果与当前的缓冲区值相加,得到新的缓冲区值。

10.重复第4~9步,直到处理完所有消息块。

11.输出哈希值:将最终的缓冲区值A、B、C、D按照指定顺序连接起来,得到128位的哈希值。

```MD5 (message)1.将消息填充为512位的块2.初始化缓冲区3.划分消息块4.遍历消息块进行处理5.初始化变量6.进行4轮循环迭代7.轮函数操作:逻辑运算、非线性函数、循环左移8.更新缓冲区9.输出哈希值```总的来说,MD5算法采用了位运算、逻辑运算以及非线性函数等操作,通过对消息的分组以及四轮的循环迭代处理,最终生成128位的消息摘要。

MD5加密概述原理以及实现

MD5加密概述原理以及实现

MD5加密概述原理以及实现MD5(Message Digest Algorithm 5)是一种常用的哈希函数,用于将任意长度的数据转换为固定长度的哈希值。

在网络传输和数据存储中,MD5广泛用于校验数据完整性,验证密码以及防止篡改等场景。

1.哈希值固定长度:无论输入数据的长度是多少,MD5算法生成的哈希值都是128位(16字节)的二进制数字。

2.唯一性:在理论上,MD5生成的哈希值应该是唯一的。

也就是说,不同的输入数据生成的哈希值不会相同。

3.不可逆性:MD5是一种单向函数,即无法通过从哈希值反向推导出原始数据。

只能通过对比不同数据的哈希值来判断其是否相同。

MD5算法的实现过程可以分为以下几个步骤:1.填充数据:将输入数据按字节切分成512位的数据段,并在数据段末尾填充一定数量的0,使其长度能被512整除。

2.初始化缓冲区:定义四个32位的缓冲区(A、B、C、D),作为算法计算的中间结果。

3.处理数据段:对每个数据段进行相同的处理流程,包括四轮的循环压缩和变换操作。

4.输出结果:将最后一次处理后的缓冲区内容按顺序连接起来,形成128位的MD5哈希值。

具体的实现细节如下:1.填充数据:如果输入数据的长度不能被512整除,就在末尾填充一个1和若干个0,使得填充后的长度满足对512取余等于448、之后,再在末尾追加64位的原始数据长度,以二进制形式表示。

2.初始化缓冲区:将四个32位的缓冲区(A、B、C、D)初始化为固定的初始值。

3.处理数据段:将每个数据段分为16个32位的子块,对每个子块进行以下四轮的循环压缩和变换操作。

-第一轮循环:通过对字节数组进行位运算,将每个子块与缓冲区中的四个值进行一系列的逻辑运算,然后更新缓冲区的值。

-第二轮循环:将第一轮循环得到的缓冲区值重新排列并加上一个常量,然后再进行一系列的逻辑运算。

-第三轮循环:将第二轮循环得到的缓冲区值再次进行一系列的逻辑运算。

-第四轮循环:将第三轮循环得到的缓冲区值再次进行一系列的逻辑运算。

MD5算法的设计与实现

MD5算法的设计与实现

实验三 MD5算法的设计与实现一、实验目的:设计并实现MD5算法,从而进一步加深对数据完整性保证和散列函数的理解。

二、实验要求:1、产生任意电子文档(包括文本和二进制)的128位信息摘要。

2、根据信息摘要验证该电子文档是否被更改过。

三、实验内容:1、MD5算法简介:Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。

1991年,Rivest开发出技术上更为趋近成熟的md5算法。

它在MD4的基础上增加了"安全-带子"(safety-belts)的概念。

虽然MD5比MD4复杂度大一些,但却更为安全。

这个算法很明显的由四个和MD4设计有少许不同的步骤组成。

在MD5算法中,信息-摘要的大小和填充的必要条件与MD4完全相同。

Den boer和Bosselaers曾发现MD5算法中的假冲突(pseudo-collisions),但除此之外就没有其他被发现的加密后结果了。

对MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

2. MD5算法逻辑处理操作包括以下几步:步骤一:附加填充比特。

对报文填充使报文的长度(比特数)与448模512同余。

即填充比特使长度为512的整数倍减去64。

例如,如果报文是448比特长,那么将填充512比特形成960比特的报文。

填充比特串的最高位为1,其余各位均为0。

步骤二:附加长度值。

将用64比特表示的初始报文(填充前)的位长度附加在步骤一的结果后(低位字节优先)。

如果初始长度大于264,仅使用该长度的低64比特。

这样,该域所包含的长度值为初始报文长度模264的值。

这两步的结果将产生一个长度为512整数倍比特的报文。

MD5算法简介及编程实现

MD5算法简介及编程实现

实验三MD5算法实验目的:1.了解哈希函数的概念和功能,以及一些典型的哈希函数2.进一步理解MD5算法的概念及结构,掌握MD5算法对数据的处理过程3.通过编程模拟MD5算法的处理步骤实验内容:一.MD5算法概述MD5算法是一种消息摘要算法(Message Digest Algorithm),此算法以任意长度的信息(message)作为输入进行计算,产生一个128-bit(16-byte)的指纹或报文摘要(fingerprint or message digest)。

两个不同的message产生相同message digest的几率相当小,从一个给定的message digest逆向产生原始message更是困难,因此MD5算法适合用在数字签名应用中。

MD5实现简单,在32位的机器上运行速度也相当快,当然实际应用也不仅仅局限于数字签名。

MD5算法的处理步骤:第一步:增加填充增加padding使得数据长度(bit为单位)模512为448。

如果数据长度正好是模512为448,增加512个填充bit,也就是说填充的个数为1-512。

第一个bit为1,其余全部为0。

(即第一个字节为0x80)第二步:补足长度将数据长度转换为64bit的数值,如果长度超过64bit所能表示的数据长度的范围,值保留最后64bit,增加到前面填充的数据后面,使得最后的数据为512bit的整数倍。

也就是32bit的16倍的整数倍。

在RFC1321中,32bit称为一个word。

第三步:初始化变量:用到4个变量,分别为A、B、C、D,均为32bit长。

初始化为:A: 0x01234567B: 0x89abcdefC: 0xfedcba98D: 0x76543210第四步:数据处理首先定义4个辅助函数:F(X,Y,Z) = XY v not(X) ZG(X,Y,Z) = XZ v Y not(Z)H(X,Y,Z) = X xor Y xor ZI(X,Y,Z) = Y xor (X v not(Z))其中:XY表示按位与,X v Y表示按位或,not(X)表示按位取反。

MD5实验报告范文

MD5实验报告范文

MD5实验报告范文实验报告:MD5算法的原理、实验过程及结果分析1.实验目的MD5(Message-Digest Algorithm 5)是一种常用的哈希算法,主要用于对消息进行完整性校验和数字签名等应用。

本实验旨在探究MD5算法的原理及实现过程,并通过实验验证其正确性和有效性。

2.实验原理MD5算法主要包括以下步骤:(1)填充消息首先,将消息进行填充,使其长度能够被512位整除。

填充方式为在消息末尾添加一个'1',然后添加若干个'0',以确保消息末尾有64位的原始消息长度。

(2)初始化缓冲区(3)消息分组将填充后的消息按512位分组,每组包含16个32位的子分组。

(4)循环压缩函数对每个分组进行四轮循环操作,共64轮。

每一轮包含四个步骤:F 函数、G函数、H函数和I函数。

每个函数分别对A、B、C、D进行操作,并根据当前轮数选择不同的方式对数据进行置换和变换。

(5)累加结果每轮循环后,计算出的A、B、C、D将与缓冲区中的原始值进行累加。

(6)输出结果经过64轮循环后,得到的缓冲区即为MD5的输出结果。

3.实验过程(1)理论分析根据MD5算法的原理,我们可以分析MD5的输入为任意长度的消息,输出为固定长度(128位)的哈希值。

MD5算法具有较高的计算效率和较好的抗碰撞性能。

(2)实验步骤a.编写MD5算法的编程代码,包括填充消息、初始化缓冲区、消息分组、循环压缩函数等步骤。

b.准备不同长度的测试消息,包括短消息和长消息。

c.分别对不同长度的消息进行哈希计算,并记录计算时间。

d.比较计算结果与预设结果是否一致。

4.实验结果分析经过实验,我们得到了如下结果:(1)对于短消息(长度小于512位),MD5能够在较短时间内完成计算,且计算结果与预设结果一致。

(2)对于长消息(长度大于512位),MD5的计算时间随着消息长度的增加而增加,但计算结果始终保持一致和正确。

5.结论与总结MD5算法是一种常用的哈希算法,具有较高计算效率和较好的抗碰撞性能。

MD5加密算法原理及实现

MD5加密算法原理及实现

MD5加密算法原理及实现MD5消息摘要算法,属Hash算法⼀类。

MD5算法对输⼊任意长度的消息进⾏运⾏,产⽣⼀个128位的消息摘要。

以下所描述的消息长度、填充数据都以位(Bit)为单位,字节序为⼩端字节。

算法原理1、数据填充对消息进⾏数据填充,使消息的长度对512取模得448,设消息长度为X,即满⾜X mod 512=448。

根据此公式得出需要填充的数据长度。

填充⽅法:在消息后⾯进⾏填充,填充第⼀位为1,其余为0。

2、添加消息长度在第⼀步结果之后再填充上原消息的长度,可⽤来进⾏的存储长度为64位。

如果消息长度⼤于264,则只使⽤其低64位的值,即(消息长度对 264取模)。

在此步骤进⾏完毕后,最终消息长度就是512的整数倍。

3、数据处理准备需要⽤到的数据:4个常数: A = 0x67452301, B = 0x0EFCDAB89, C = 0x98BADCFE, D = 0x10325476;4个函数:F(X,Y,Z)=(X & Y) | ((~X) & Z); G(X,Y,Z)=(X & Z) | (Y & (~Z)); H(X,Y,Z)=X ^ Y ^ Z; I(X,Y,Z)=Y ^ (X | (~Z));把消息分以512位为⼀分组进⾏处理,每⼀个分组进⾏4轮变换,以上⾯所说4个常数为起始变量进⾏计算,重新输出4个变量,以这4个变量再进⾏下⼀分组的运算,如果已经是最后⼀个分组,则这4个变量为最后的结果,即MD5值。

具体计算的实现较为复杂,建议查阅相关书籍,下⾯给出在C++上的实现代码。

代码实现#MD5.h1 #ifndef MD5H2 #define MD5H3 #include <math.h>4 #include <Windows.h>56 void ROL(unsigned int &s, unsigned short cx); //32位数循环左移实现函数7 void ltob(unsigned int &i); //B\L互转,接受UINT类型8 unsigned int* MD5(const char* mStr); //接⼝函数,并执⾏数据填充,计算MD5时调⽤此函数910 #endif #MD5.cpp1 #include "MD5.h"23 /*4组计算函数*/4 inline unsigned int F(unsigned int X, unsigned int Y, unsigned int Z)5 {6 return (X & Y) | ((~X) & Z);7 }8 inline unsigned int G(unsigned int X, unsigned int Y, unsigned int Z)9 {10 return (X & Z) | (Y & (~Z));11 }12 inline unsigned int H(unsigned int X, unsigned int Y, unsigned int Z)13 {14 return X ^ Y ^ Z;15 }16 inline unsigned int I(unsigned int X, unsigned int Y, unsigned int Z)17 {18 return Y ^ (X | (~Z));19 }20 /*4组计算函数结束*/2122 /*32位数循环左移实现函数*/23 void ROL(unsigned int &s, unsigned short cx)24 {25 if (cx > 32)cx %= 32;26 s = (s << cx) | (s >> (32 - cx));27 return;28 }2930 /*B\L互转,接收UINT类型*/31 void ltob(unsigned int &i)32 {33 unsigned int tmp = i;//保存副本34 byte *psour = (byte*)&tmp, *pdes = (byte*)&i;35 pdes += 3;//调整指针,准备左右调转36 for (short i = 3; i >= 0; --i)37 {38 CopyMemory(pdes - i, psour + i, 1);39 }40 return;41 }4243 /*44 MD5循环计算函数,label=第⼏轮循环(1<=label<=4),lGroup数组=4个种⼦副本,M=数据(16组32位数指针)45 种⼦数组排列⽅式: --A--D--C--B--,即 lGroup[0]=A; lGroup[1]=D; lGroup[2]=C; lGroup[3]=B;46 */47 void AccLoop(unsigned short label, unsigned int *lGroup, void *M)48 {49 unsigned int *i1, *i2, *i3, *i4, TAcc, tmpi = 0; //定义:4个指针; T表累加器;局部变量50 typedef unsigned int(*clac)(unsigned int X, unsigned int Y, unsigned int Z); //定义函数类型51 const unsigned int rolarray[4][4] = {52 { 7, 12, 17, 22 },53 { 5, 9, 14, 20 },54 { 4, 11, 16, 23 },55 { 6, 10, 15, 21 }56 };//循环左移-位数表57 const unsigned short mN[4][16] = {58 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },59 { 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12 },60 { 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2 },61 { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }62 };//数据坐标表63 const unsigned int *pM = static_cast<unsigned int*>(M);//转换类型为32位的Uint64 TAcc = ((label - 1) * 16) + 1; //根据第⼏轮循环初始化T表累加器65 clac clacArr[4] = { F, G, H, I }; //定义并初始化计算函数指针数组6667 /*⼀轮循环开始(16组->16次)*/68 for (short i = 0; i < 16; ++i)69 {70 /*进⾏指针⾃变换*/71 i1 = lGroup + ((0 + i) % 4);72 i2 = lGroup + ((3 + i) % 4);73 i3 = lGroup + ((2 + i) % 4);74 i4 = lGroup + ((1 + i) % 4);7576 /*第⼀步计算开始: A+F(B,C,D)+M[i]+T[i+1] 注:第⼀步中直接计算T表*/77 tmpi = (*i1 + clacArr[label - 1](*i2, *i3, *i4) + pM[(mN[label - 1][i])] + (unsigned int)(0x100000000UL * abs(sin((double)(TAcc + i)))));78 ROL(tmpi, rolarray[label - 1][i % 4]);//第⼆步:循环左移79 *i1 = *i2 + tmpi;//第三步:相加并赋值到种⼦80 }81 return;82 }8384 /*接⼝函数,并执⾏数据填充*/85 unsigned int* MD5(const char* mStr)86 {87 unsigned int mLen = strlen(mStr); //计算字符串长度88 if (mLen < 0) return 0;89 unsigned int FillSize = 448 - ((mLen * 8) % 512); //计算需填充的bit数90 unsigned int FSbyte = FillSize / 8; //以字节表⽰的填充数91 unsigned int BuffLen = mLen + 8 + FSbyte; //缓冲区长度或者说填充后的长度92 unsigned char *md5Buff = new unsigned char[BuffLen]; //分配缓冲区93 CopyMemory(md5Buff, mStr, mLen); //复制字符串到缓冲区9495 /*数据填充开始*/96 md5Buff[mLen] = 0x80; //第⼀个bit填充197 ZeroMemory(&md5Buff[mLen + 1], FSbyte - 1); //其它bit填充0,另⼀可⽤函数为FillMemory98 unsigned long long lenBit = mLen * 8ULL; //计算字符串长度,准备填充99 CopyMemory(&md5Buff[mLen + FSbyte], &lenBit, 8); //填充长度100 /*数据填充结束*/101102 /*运算开始*/103 unsigned int LoopNumber = BuffLen / 64; //以16个字为⼀分组,计算分组数量104 unsigned int A = 0x67452301, B = 0x0EFCDAB89, C = 0x98BADCFE, D = 0x10325476;//初始4个种⼦,⼩端类型105 unsigned int *lGroup = new unsigned int[4]{ A, D, C, B}; //种⼦副本数组,并作为返回值返回106 for (unsigned int Bcount = 0; Bcount < LoopNumber; ++Bcount) //分组⼤循环开始107 {108 /*进⼊4次计算的⼩循环*/109 for (unsigned short Lcount = 0; Lcount < 4;)110 {111 AccLoop(++Lcount, lGroup, &md5Buff[Bcount * 64]);112 }113 /*数据相加作为下⼀轮的种⼦或者最终输出*/114 A = (lGroup[0] += A);115 B = (lGroup[3] += B);116 C = (lGroup[2] += C);117 D = (lGroup[1] += D);118 }119 /*转换内存中的布局后才能正常显⽰*/120 ltob(lGroup[0]);121 ltob(lGroup[1]);122 ltob(lGroup[2]);123 ltob(lGroup[3]);124 delete[] md5Buff; //清除内存并返回125 return lGroup;126 }再给出调⽤实例(以win32控制台应⽤程序为例):#main.cpp#include <iostream>2 #include <string.h>3 #include <stdlib.h>4 #include "MD5.h"56 int main(int argc, char **argv)7 {8 char tmpstr[256], buf[4][10];9 std::cout << "请输⼊要加密的字符串:";10 std::cin >> tmpstr;11 unsigned int* tmpGroup = MD5(tmpstr);12 sprintf_s(buf[0], "%8X", tmpGroup[0]);13 sprintf_s(buf[1], "%8X", tmpGroup[3]);14 sprintf_s(buf[2], "%8X", tmpGroup[2]);15 sprintf_s(buf[3], "%8X", tmpGroup[1]);16 std::cout <<"MD5:"<< buf[0] << buf[1] << buf[2] << buf[3] << std::endl;1718 delete[] tmpGroup;19 return 0; //在此下断点才能看到输出的值20 }复制代码。

MD5算法原理及代码实现

MD5算法原理及代码实现

MD5算法原理及代码实现MD5(Message Digest Algorithm 5)是一种被广泛使用的消息摘要算法,它是MD家族中的第五个版本。

MD5算法能将任意长度的输入数据转换为一个128位(16字节)的散列值,通常表示为32个十六进制数。

1. 填充(Padding):为了使输入消息的位数对512求余数等于448,填充是必要的。

例如,如果输入消息的位数是L,填充后的消息长度为K* 512 + 448,其中K是一个非负整数。

填充后的消息被分为512位(64字节)的块。

2. 初始化(Initialization):算法对四个32位的缓冲区A、B、C、D进行初始化,通常初始化为常量。

这些缓冲区用于保存中间计算结果。

3. 循环(Iteration):通过进行四轮循环的操作,将每个512位的块以及前一个块的连续散列结果作为输入,产生新的散列结果。

每轮循环包括四个步骤:数据的复制、数据的变换、数据的交换以及数据的加法。

4. 输出(Output):将最后一轮循环的输出结果根据顺序连接起来,形成128位的散列值。

下面是一个简单的MD5算法的代码示例,使用Python语言实现:```pythonimport hashlibdef md5(message):md5_hash = hashlib.md5md5_hash.update(message.encode('utf-8'))return md5_hash.hexdigest#测试message = "Hello, world!"md5_value = md5(message)print("MD5 hash value:", md5_value)```在上述代码中,我们首先导入了Python标准库中的hashlib模块,该模块提供了MD5算法的实现。

然后,我们定义了一个名为md5的函数,它接受一个字符串形式的消息作为输入,并返回该消息的MD5散列值。

MD5加密算法的原理及应用

MD5加密算法的原理及应用

MD5加密算法的原理及应用MD5加密算法是一种常见的哈希算法,用于产生固定长度的摘要信息。

该算法由美国计算机安全专家罗纳德·李维斯特于1991年设计,并在1992年首次公开。

MD5是指“Message Digest Algorithm 5”的缩写。

MD5加密算法的原理是将任意长度的输入消息通过一系列操作转换为长度固定(128位)的输出摘要。

这一过程是不可逆的,即无法通过摘要信息还原出原始的输入消息。

MD5算法的核心函数包括位操作、模运算、异或运算和与非运算。

具体过程如下:1.初始填充:将输入消息分割为若干个512位的消息块,并添加填充位,使每个消息块的长度为512位。

2.初始化状态:将四个32位的寄存器A、B、C、D初始化,作为MD5算法的内部状态。

3.处理消息块:循环处理每个消息块,对每个消息块进行一系列的位运算、模运算和异或运算,修改内部状态。

4.输出:处理完所有消息块后,将最终的内部状态输出为一个128位(32位×4)的摘要。

1.文件完整性校验:MD5可以对文件进行哈希计算,生成唯一的摘要值,通过比对两个文件的MD5摘要是否一致,可以判断文件是否被篡改。

2.密码存储:在用户注册过程中,通常不会将用户的密码明文存储在数据库中,而是将其进行MD5加密后存储。

当用户登录时,输入的密码再次通过MD5加密与数据库中存储的加密密码进行对比。

4.垃圾邮件过滤:MD5可以用于检测垃圾邮件。

将邮件的正文内容通过MD5加密并与已知的垃圾邮件MD5值进行对比,可以快速判定该邮件是否为垃圾邮件。

5.数据库索引:MD5可以作为数据库索引的一部分,提高查询效率。

通过对需要索引的数据进行MD5加密,可以将一部分数据转化为固定长度的摘要,便于数据库的查询操作。

然而,由于MD5算法的安全性较低,易受到碰撞攻击(即找到不同的原始消息,但其MD5摘要值相同)和彩虹表攻击(通过预先计算MD5摘要的映射关系,快速破解密码)等攻击方式的影响,因此在一些对安全性要求较高的场景,如数据加密、验证、身份认证等领域,MD5算法已经不再推荐使用。

《信息安全》实验报告3MD5的计算和破解

《信息安全》实验报告3MD5的计算和破解

《信息安全》实验报告3MD5的计算和破解实验目标:1.了解MD5算法的基本原理。

2.掌握MD5算法的计算和应用。

3.理解MD5算法的弱点,并尝试破解MD5哈希值。

一、实验原理:MD5(Message Digest Algorithm 5)是一种常用的消息摘要算法,用来确保数据的完整性和一致性,广泛应用于信息安全领域中。

MD5将任意长度的输入数据进行计算,得到一个128位的哈希值。

实验步骤:1.编写MD5的计算代码。

2.编写MD5的破解代码。

3.运行代码,计算给定字符串的MD5哈希值。

4.破解给定MD5哈希值。

二、实验过程:1.MD5的计算代码编写:MD5算法的计算过程包括四个主要的步骤:填充位、增加长度、初始化变量和循环计算。

a.填充位:将待计算的消息填充至512位的倍数,填充位为1后面加零。

b.增加长度:在填充消息后增加一个64位的二进制数,表示原始消息的长度。

c.初始化变量:设定固定的四个变量,用于循环计算。

d.循环计算:将填充后的消息分为512位的块进行循环计算,计算结果与前一块的结果进行累加。

2.MD5的破解代码编写:MD5的破解目标是通过已知的MD5哈希值,找到对应的原始数据。

一般的方法是尝试不同的输入数据,计算MD5哈希值,然后与已知的哈希值进行比较。

a.枚举法:通过不断尝试不同的输入数据,计算MD5哈希值与给定哈希值进行比较,直到找到对应的原始数据。

b.字典法:通过预先准备好的字典文件,将字典中的每个词进行MD5哈希计算,然后与给定哈希值进行比较,查找对应的原始数据。

3.实验结果展示:4.MD5的破解:a.枚举法:从'a'到'z'的26个字符中依次尝试,计算MD5哈希值并与给定值进行比较,直到找到对应的原始数据。

b.字典法:根据常见密码字典构建一个文本文件,逐行读取文件中的词进行MD5哈希计算并与给定值进行比较,直到找到对应的原始数据。

5.实验总结:实验中,我们通过计算MD5哈希值和尝试破解,深入了解了MD5算法的原理和应用。

MD5算法的设计与实现

MD5算法的设计与实现

MD5算法的设计与实现MD5(Message Digest Algorithm 5)是一种常用的哈希算法,用于对任意长度的数据进行加密和校验。

MD5算法由美国密码学家罗纳德·李维斯特(Ronald Rivest)于1991年提出,目前仍广泛应用于数据完整性校验、密码存储等领域。

1.不可逆性:MD5算法是单向的,无法通过哈希值逆向推导出原始数据。

这意味着即使知道哈希值,也无法还原出原始数据。

2.高度离散性:MD5算法对输入数据的任意细微更改都会产生完全不同的哈希值。

这意味着即使数据只有一点点改变,其哈希值也会完全不同。

3.快速性:MD5算法的计算速度相对较快,能够在短时间内对大量数据进行哈希计算。

1.填充数据:对输入数据进行填充,使其长度恰好为512的倍数。

填充时,在数据末尾添加一个1,后面补0至满足长度要求。

2.填充长度:将填充后的数据长度(以比特位为单位)表示为64位二进制数,并添加到填充数据的末尾。

3.初始化状态:定义四个32位的寄存器A、B、C、D,并初始化为特定的常量值。

4.分组处理:将填充后的数据分成若干个512位的分组,每次处理一个分组。

5.循环操作:对每个分组进行四轮循环操作,每轮操作包括四个步骤。

a.F函数:根据当前轮数选择不同的非线性函数,并将寄存器A、B、C、D的值传入。

b.G函数:根据当前轮数选择不同的线性函数,并将寄存器A、B、C、D的值传入。

c.H函数:根据当前轮数选择不同的线性函数,并将寄存器A、B、C、D的值传入。

d.I函数:根据当前轮数选择不同的线性函数,并将寄存器A、B、C、D的值传入。

6.更新寄存器:根据循环操作的结果更新寄存器A、B、C、D的值。

7.输出结果:将最终的寄存器值按顺序连接起来,得到128位的哈希值。

1.碰撞攻击:由于MD5算法的哈希值只有128位,因此存在不同的输入数据生成相同的哈希值的可能性,这被称为碰撞。

攻击者可以通过特定的方法找到两个不同的输入数据,生成相同的哈希值,从而绕过数据完整性校验。

MD5算法的设计与实现

MD5算法的设计与实现

MD5算法的设计与实现MD5(Message-Digest Algorithm 5)是一种广泛使用的哈希函数,用于确保数据的完整性和一致性。

它是MD4的改进版,具有更好的安全性和性能。

MD5算法的设计与实现是在密码学中的哈希函数领域中的重要研究方向之一、接下来将详细介绍MD5算法的设计思路、实现过程以及应用场景。

首先,MD5算法的设计目标是能够快速生成长度为128位(16字节)的哈希值。

这个哈希值被认为是唯一的,并且在所有可能的输入上均具有高度分散性,即使输入的微小改变也会产生完全不同的哈希值。

1.数据填充:首先将输入数据进行填充,使其长度满足512位(64字节)的倍数。

填充的方式是在数据的末尾添加一个比特“1”,然后添加足够数量的零比特,以保证填充后的数据长度满足要求。

2.消息分组:将填充后的数据分割为多个512位(64字节)的消息分组。

由于输入数据的长度可以是任意长度,因此消息分组的数量可能不止一个。

3.初始化状态:MD5算法使用四个32位(4字节)的状态变量(A、B、C、D)来计算哈希值。

初始时,这四个状态变量被设置为特定的常数值,用于指示算法的起始状态。

4.循环运算:对每个消息分组进行一系列的循环运算,包括四轮主循环和每轮循环中的16轮子循环。

每轮子循环都涉及到不同的置换函数和常数,以保证算法的不可逆性和混淆性。

5.输出摘要:最后,将经过循环运算后的状态变量相连,并将它们的值转化为16进制字符串,即得到128位(16字节)的哈希值。

MD5算法广泛应用于网络传输和存储中,以确保数据的完整性。

例如,在文件传输过程中,发送方可以使用MD5算法计算文件的哈希值,并将其连同文件一起发送给接收方。

接收方可以使用相同的MD5算法对接收到的文件进行哈希值计算,并将结果与接收到的哈希值进行比较,以验证文件的完整性。

如果哈希值一致,则说明文件未被修改;如果哈希值不一致,则说明文件可能已被篡改或损坏。

此外,MD5算法还常用于密码存储。

MD5加密算法原理及其应用

MD5加密算法原理及其应用

MD5加密算法原理及其应用MD5(Message Digest Algorithm 5)是一种常用的哈希函数(Hash Function),它由美国密码学家罗纳德·李维斯特(Ronald Rivest)设计于1991年。

MD5算法具有不可逆性、固定长度和高敏感度等特点,主要用于数据完整性校验和用户密码存储。

MD5算法的原理是将任意长度的数据(输入消息)通过一系列复杂的计算过程,生成一个128-bit的哈希值(消息摘要)。

具体步骤如下:1. 填充:首先,将消息填充到512-bit的倍数,使得消息长度满足(448 mod 512)。

填充方式为在消息末尾添加一个"1"位,然后添加若干个"0"位,使得消息长度 mod 512 = 448,并以64位的二进制表示消息原始长度。

2. 初始化:定义4个32-bit的寄存器A、B、C、D,并初始化为特定的常量值。

此外,定义一个64个元素的常数表T,用作计算过程中的常数。

3. 分组处理:将填充后的消息分割成512-bit的分组,并对每个分组进行处理。

a.将A、B、C、D的值初始化为上一分组处理结果。

b. 定义4个辅助变量Mj,将处理分组拆分为16个32-bit的消息字,填入Mj。

c.依次进行4轮循环操作,每轮循环进行16次迭代运算。

每次迭代使用特定的非线性函数和循环位移。

4. 输出结果:将经过多轮循环计算后得到的最终结果A、B、C、D进行拼接,即可得到128-bit的哈希值。

MD5算法的应用十分广泛,以下是几个常见的应用场景:1.文件完整性校验:MD5可以根据文件内容生成一个唯一的哈希值,通过比对哈希值可以验证文件是否在传输或存储过程中被篡改或损坏。

2.用户密码存储:MD5可以对用户密码进行加密后存储,提高密码的安全性。

用户登录时,输入的密码经过MD5加密后与存储在数据库中的密码进行比对,从而实现密码的验证。

3.数字签名:数字签名是为了保证数据的完整性、身份认证和抗抵赖性。

MD5加密C语言实现

MD5加密C语言实现

MD5加密C语言实现MD5(Message-Digest Algorithm 5)是一种广泛使用的散列函数,它将任意长度的数据映射为固定长度的散列值。

在本文中,我们将实现一个简单的MD5加密算法的C语言版本。

1.MD5加密算法的基本原理:MD5算法由四个基本步骤组成:填充,初始化,循环计算和摘要。

-填充:将需要加密的数据填充到一个长度为64的倍数的消息块,填充内容为一个1和若干个0,在结尾添加64位表示原始消息长度的二进制表示。

-初始化:初始化四个64位的缓冲区,用于存储计算结果。

-循环计算:将填充后的数据分为若干个消息块,每个消息块都经过四个循环处理(共64轮),根据一系列的位运算对缓冲区进行更新。

-摘要:将经过循环计算后的结果拼接起来,得到最终的128位摘要。

2.C语言实现:下面是一个简单的C语言版本的MD5加密算法实现。

该实现基于RFC1321中的伪代码。

首先,我们需要定义一些常数和辅助函数:```c#include <stdio.h>#include <stdint.h>//初始化缓冲区//将字符串转换为二进制消息块void stringToBinary(const char *str, uint32_t *msg, uint32_t len)uint32_t i;for (i = 0; i < len; i++)msg[i] = ((uint32_t)str[i * 4 + 3] << 24) ,((uint32_t)str[i * 4 + 2] << 16)((uint32_t)str[i * 4 + 1] << 8) , (uint32_t)str[i * 4];}//辅助函数:循环左移uint32_t rotateLeft(uint32_t x, uint32_t n)return (x << n) , (x >> (32 - n));```接下来,我们可以实现MD5算法的四个步骤:-填充:```c//填充消息块void padding(uint32_t *msg, uint32_t len)uint32_t midBitLength = len * 4 * 8;uint32_t padLen = ((midBitLength + 8) / 512 + 1) * 512 / 32 - len; // 计算填充长度msg[len] = 0x80; // 添加一个1uint32_t i;for (i = len + 1; i < len + padLen - 8; i++)msg[i] = 0x00; // 其余位置0}```-初始化:```c//初始化缓冲区void initBufferbuffer[1] = 0xEFCDAB89;buffer[2] = 0x98BADCFE;```-循环计算:```c//对每个消息块进行循环计算void processBlock(uint32_t *block)uint32_t a = buffer[0], b = buffer[1], c = buffer[2], d = buffer[3];uint32_t i;//主循环,共64轮for (i = 0; i < 64; i++)uint32_t f, g;//根据i的值选取相应的函数和常数if (i < 16)f=(b&c),((~b)&d);g=i;}else if (i < 32)f=(d&b),((~d)&c);g=(5*i+1)%16;}else if (i < 48)f=b^c^d;g=(3*i+5)%16;}elsef=c^(b,(~d));g=(7*i)%16;}uint32_t temp = d;d=c;c=b;b = b + rotateLeft(a + f + k[i] + block[g], s[i]);a = temp;}//更新缓冲区buffer[0] += a;buffer[1] += b;buffer[2] += c;buffer[3] += d;```-摘要:```c//生成最终的摘要void generateDigest(uint32_t *msg, uint32_t len)uint32_t i;for (i = 0; i < len / 16; i++)processBlock(msg + i * 16);}```最后,我们可以编写一个简单的主函数来使用这些函数:```cint main//待加密的字符串const char *str = "Hello, MD5!";uint32_t msgLength = (uint32_t)(strlen(str) + 1) / 4; //将字符串转换为二进制消息块uint32_t msg[msgLength];stringToBinary(str, msg, msgLength);//加密padding(msg, msgLength);initBuffer(;generateDigest(msg, msgLength + 64 / 4);//输出结果printf("MD5: ");for (int i = 0; i < 4; i++)printf("%02x", buffer[i] >> 0 & 0xff);printf("%02x", buffer[i] >> 8 & 0xff);printf("%02x", buffer[i] >> 16 & 0xff);printf("%02x", buffer[i] >> 24 & 0xff);}printf("\n");return 0;```这个简单的C语言版本的MD5加密算法实现了填充,初始化,循环计算和摘要等基本步骤。

MD5算法的设计与实现

MD5算法的设计与实现

MD5算法的设计与实现MD5是一种广泛使用的哈希算法,用于将任意长度的数据转化为固定长度的哈希值。

它由美国密码学家罗纳德·李维斯特(Ronald Rivest)设计并在1991年公开发布。

它使用64位长度的哈希值,通常以32位十六进制数表示。

MD5广泛应用于密码学、数据完整性校验等领域。

MD5的设计目标是能够快速且简单地计算出哈希值,以及在输入数据发生变化时能够快速更新哈希值。

其基本思想是将输入数据按块进行分割,并通过一系列的分组运算、位运算和非线性函数来进行处理,最终得到哈希值。

MD5的实现过程可以分为4个步骤:1.填充数据:首先,将输入数据按字节进行填充,使其长度满足对512位(64个字节)取模后余数为448的条件。

填充的方式是在数据末尾添加一个1,然后填充若干个0,使得数据的长度满足上述条件。

2.进行分组处理:将填充后的数据划分为512位(64个字节)的分组,每个分组又划分为16个32位字。

3.初始化哈希值:将初始化的哈希值(A、B、C、D)分别设置为固定的32位常数,这些常数是对平方根的绝对值的整数部分位的前32位的小数部分的小数点左边32位转化而成。

4.执行四轮循环:每轮循环包括16个迭代,每个迭代依次进行四个运算:F、G、H和I。

每个迭代的结果与前一轮迭代的结果相关,具体顺序和方式是固定的,并且单个迭代之间的次序满足一定的规律。

在每轮循环的最后,将当前分组的计算结果与上一轮的哈希值相加,并更新哈希值。

最终,经过所有分组的处理后,得到的哈希值即为MD5算法的输出结果。

MD5算法的实现要求具备高效的运算速度、良好的安全性和抗碰撞性。

虽然在设计之初,MD5算法被广泛应用于密码学和数据完整性校验,但由于存在一些安全性问题,如存在碰撞攻击(两个不同的输入可以产生相同的哈希值),其在实际应用中已经被更安全的算法,如SHA-1和SHA-256所取代。

总结来说,MD5算法是一种广泛应用的哈希算法,通过一系列分组运算、位运算和非线性函数的处理,将任意长度的数据转化为固定长度的哈希值。

md5密码杂凑算法

md5密码杂凑算法

md5密码杂凑算法
MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。

MD5是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。

MD5的原理和实现过程如下:
1. 填充:首先,将信息进行填充,使其长度恰好是512的整数倍。

填充的
方法是第一位填充1,其余位填充0。

填充完后,信息的长度就是
512N+448。

之后,用剩余的位置=64位)记录原文的真正长度,把长度
的二进制值补在最后。

这样处理后的信息长度就是512(N+1)。

2. 设置初始值:MD5的哈希结果长度为128位,按每32位分成一组共4组。

这4组结果是由4个初始值A、B、C、D经过不断演变得到。

3. 信息分块:将处理后的信息分成512位的小块,每小块再进行一系列的
数学运算,最终得到一个128位的哈希值。

通过以上步骤,可以将任意长度的数据运算为另一固定长度值,这是杂凑算法的基础原理。

MD5算法具有以下特点:
1. 压缩性:任意长度的数据,算出的MD5值长度都是固定的。

2. 容易计算:从原数据计算出MD5值很容易。

3. 抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。

4. 强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

以上信息仅供参考,如需获取更多详细信息,建议查阅MD5相关的书籍或咨询专业技术人员。

md5加密算法的原理和应用

md5加密算法的原理和应用

MD5加密算法的原理和应用1. 简介MD5(Message Digest Algorithm 5)是一种广泛应用的密码散列函数,用于对消息进行加密。

它是MD系列算法的第五个版本,于1992年由罗纳德·李维斯特(Ronald Rivest)设计开发。

MD5算法通过将消息逐块进行处理,生成一个128位(16字节)的散列值。

本文将介绍MD5加密算法的原理以及其应用领域。

2. MD5加密算法的原理MD5算法的核心原理是将输入的消息分解成固定大小的块,并对每个块进行一系列的位运算,最终生成一个固定长度的散列值。

下面是MD5算法的核心步骤:1.消息填充:将输入消息的长度补位到64位的倍数,通常使用一个1和若干个0进行填充。

填充后的消息长度为64位的整数倍。

2.初始化:初始化MD5算法的四个32位寄存器A、B、C和D的初值,这些初值被定义为固定的常数。

3.处理块:将填充后的消息划分为若干个64位的块。

对于每个块,算法将进行以下四轮的变换操作:–第一轮:使用一个特定的非线性函数F和一个固定的随机常数K,对寄存器A、B、C和D进行一系列的位运算。

–第二轮:通过将寄存器D赋值给寄存器C,寄存器C赋值给寄存器B,寄存器B赋值给寄存器A,寄存器A赋值给寄存器D,并对寄存器A进行一系列的位运算。

–第三轮:通过将寄存器C赋值给寄存器B,寄存器B赋值给寄存器A,寄存器A赋值给寄存器D,寄存器D赋值给寄存器C,并对寄存器A进行一系列的位运算。

–第四轮:通过将寄存器B赋值给寄存器A,寄存器A赋值给寄存器D,寄存器D赋值给寄存器C,寄存器C赋值给寄存器B,并对寄存器A进行一系列的位运算。

4.生成散列值:最后,将四个寄存器的值按照A、B、C、D的顺序连接起来,得到一个128位(16字节)的散列值。

3. MD5加密算法的应用MD5加密算法具有以下几个主要的应用领域:3.1 密码存储MD5算法常用于存储用户密码。

当用户注册或更改密码时,系统会将用户输入的明文密码经过MD5加密后存储在数据库中。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验三 MD5算法的设计与实现一、实验目的:设计并实现MD5算法,从而进一步加深对数据完整性保证和散列函数的理解。

二、实验要求:1、产生任意电子文档(包括文本和二进制)的128位信息摘要。

2、根据信息摘要验证该电子文档是否被更改过。

三、实验内容:1、MD5算法简介:Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。

1991年,Rivest开发出技术上更为趋近成熟的md5算法。

它在MD4的基础上增加了"安全-带子"(safety-belts)的概念。

虽然MD5比MD4复杂度大一些,但却更为安全。

这个算法很明显的由四个和MD4设计有少许不同的步骤组成。

在MD5算法中,信息-摘要的大小和填充的必要条件与MD4完全相同。

Den boer和Bosselaers曾发现MD5算法中的假冲突(pseudo-collisions),但除此之外就没有其他被发现的加密后结果了。

对MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

2. MD5算法逻辑处理操作包括以下几步:步骤一:附加填充比特。

对报文填充使报文的长度(比特数)与448模512同余。

即填充比特使长度为512的整数倍减去64。

例如,如果报文是448比特长,那么将填充512比特形成960比特的报文。

填充比特串的最高位为1,其余各位均为0。

步骤二:附加长度值。

将用64比特表示的初始报文(填充前)的位长度附加在步骤一的结果后(低位字节优先)。

如果初始长度大于264,仅使用该长度的低64比特。

这样,该域所包含的长度值为初始报文长度模264的值。

这两步的结果将产生一个长度为512整数倍比特的报文。

经扩展的报文表示成512比特的分组序列列Y1、Y2、Y3……Y(n-1),因此扩展的报文长度等于L乘512比特。

与之等价的是,该结果也等于字长为16比特或32比特的整数倍,如果让[]10−NML表示扩展报文包含的字数,其中N是16的倍数,则N等于L 乘512。

下图为使用MD5产生报文摘要的过程:步骤三:初始化MD缓存。

使用一个128比特的缓存来存放该散列函数的中间值及最终结果。

该缓存可表示为4个32比特的寄存器(ABCD)。

A=67452301,B=EFCDAB89,C=98BADCFE,D=10325476,这些值以低位字节放在在前的格式存储: A=01234567,B=89ABCDEF,C=FEDCBA98,D=76543210步骤四:处理512比特报文分组序列。

算法的核心是一个包含四个“循环”的压缩函数,下图为单个512比特分组MD5处理过程:四个循环有相似的结构,但每次循环使用不同的原始逻辑函数,说明中表示为FGHI。

每一循环都以当前的正在处理的512比特分组(Yq)和128比特的缓存值ABCD为输入,然后更新缓存的内容。

每一循环使用一个64元素表T[0…64]的四分之一,该表通过正弦函数构建。

T的第i个元素(表示为[Ti])的值等于的整数部分值其中i的单位是弧度。

因为是0到1之间的数,每个T 的值均能用32比特表示集,它将消除输入数据的任何规律性。

第四次循环的输出加到第一次循环的输入(CVq)上产生(CV q+1),相加是缓存四个字与(CVq)中对应四个字以模相加。

步骤五:输出。

所有L个512比特的分组处理完成后,第L阶段产生的输出便是128比特的报文摘要。

总结MD5的操作如下:其中: IV=缓存ABCD的初值,在步骤三定义Yq=第q个长度为512比特的报文分组L=报文(包括填充字段和长度字段)的分组数CVq=处理第q个报文分组时的连接变量RFx=使用原始逻辑函数x的循环函数MD=最终的报文摘要SUM32=对输入对中的每个字分别执行模相加3、MD5的安全性:md5相对md4所作的改进:a. 增加了第四轮;b. 每一步均有唯一的加法常数;c. 为减弱第二轮中函数g的对称性从(x&y)|(x&z)|(y&z)变为(x&z)|(y&(~z));d. 第一步加上了上一步的结果,这将引起更快的雪崩效应;e. 改变了第二轮和第三轮中访问消息子分组的次序,使其更不相似;f. 近似优化了每一轮中的循环左移位移量以实现更快的雪崩效应。

各轮的位移量互不相同。

4.设计MD5算法:(1)、MD5ChecksumDefines.h(定义相关常量的头文件)//Magic initialization constants#define MD5_INIT_STATE_0 0x67452301#define MD5_INIT_STATE_1 0xefcdab89#define MD5_INIT_STATE_2 0x98badcfe#define MD5_INIT_STATE_3 0x10325476//Constants for Transform routine.#define MD5_S11 7#define MD5_S12 12#define MD5_S13 17#define MD5_S14 22#define MD5_S21 5#define MD5_S22 9#define MD5_S23 14#define MD5_S24 20#define MD5_S31 4#define MD5_S32 11#define MD5_S33 16#define MD5_S34 23#define MD5_S41 6#define MD5_S42 10#define MD5_S43 15#define MD5_S44 21//Transformation Constants - Round 1#define MD5_T01 0xd76aa478 //Transformation Constant 1 #define MD5_T02 0xe8c7b756 //Transformation Constant 2 #define MD5_T03 0x242070db //Transformation Constant 3 #define MD5_T04 0xc1bdceee //Transformation Constant 4 #define MD5_T05 0xf57c0faf //Transformation Constant 5 #define MD5_T06 0x4787c62a //Transformation Constant 6 #define MD5_T07 0xa8304613 //Transformation Constant 7 #define MD5_T08 0xfd469501 //Transformation Constant 8 #define MD5_T09 0x698098d8 //Transformation Constant 9 #define MD5_T10 0x8b44f7af //Transformation Constant 10 #define MD5_T11 0xffff5bb1 //Transformation Constant 11 #define MD5_T12 0x895cd7be //Transformation Constant 12 #define MD5_T13 0x6b901122 //Transformation Constant 13 #define MD5_T14 0xfd987193 //Transformation Constant 14 #define MD5_T15 0xa679438e //Transformation Constant 15 #define MD5_T16 0x49b40821 //Transformation Constant 16 //Transformation Constants - Round 2#define MD5_T17 0xf61e2562 //Transformation Constant 17#define MD5_T19 0x265e5a51 //Transformation Constant 19 #define MD5_T20 0xe9b6c7aa //Transformation Constant 20 #define MD5_T21 0xd62f105d //Transformation Constant 21 #define MD5_T22 0x02441453 //Transformation Constant 22 #define MD5_T23 0xd8a1e681 //Transformation Constant 23 #define MD5_T24 0xe7d3fbc8 //Transformation Constant 24 #define MD5_T25 0x21e1cde6 //Transformation Constant 25 #define MD5_T26 0xc33707d6 //Transformation Constant 26 #define MD5_T27 0xf4d50d87 //Transformation Constant 27 #define MD5_T28 0x455a14ed //Transformation Constant 28 #define MD5_T29 0xa9e3e905 //Transformation Constant 29 #define MD5_T30 0xfcefa3f8 //Transformation Constant 30 #define MD5_T31 0x676f02d9 //Transformation Constant 31 #define MD5_T32 0x8d2a4c8a //Transformation Constant 32 //Transformation Constants - Round 3#define MD5_T33 0xfffa3942 //Transformation Constant 33 #define MD5_T34 0x8771f681 //Transformation Constant 34 #define MD5_T35 0x6d9d6122 //Transformation Constant 35 #define MD5_T36 0xfde5380c //Transformation Constant 36 #define MD5_T37 0xa4beea44 //Transformation Constant 37 #define MD5_T38 0x4bdecfa9 //Transformation Constant 38#define MD5_T40 0xbebfbc70 //Transformation Constant 40 #define MD5_T41 0x289b7ec6 //Transformation Constant 41 #define MD5_T42 0xeaa127fa //Transformation Constant 42 #define MD5_T43 0xd4ef3085 //Transformation Constant 43 #define MD5_T44 0x04881d05 //Transformation Constant 44 #define MD5_T45 0xd9d4d039 //Transformation Constant 45 #define MD5_T46 0xe6db99e5 //Transformation Constant 46 #define MD5_T47 0x1fa27cf8 //Transformation Constant 47 #define MD5_T48 0xc4ac5665 //Transformation Constant 48 //Transformation Constants - Round 4#define MD5_T49 0xf4292244 //Transformation Constant 49 #define MD5_T50 0x432aff97 //Transformation Constant 50 #define MD5_T51 0xab9423a7 //Transformation Constant 51 #define MD5_T52 0xfc93a039 //Transformation Constant 52 #define MD5_T53 0x655b59c3 //Transformation Constant 53 #define MD5_T54 0x8f0ccc92 //Transformation Constant 54 #define MD5_T55 0xffeff47d //Transformation Constant 55 #define MD5_T56 0x85845dd1 //Transformation Constant 56 #define MD5_T57 0x6fa87e4f //Transformation Constant 57 #define MD5_T58 0xfe2ce6e0 //Transformation Constant 58 #define MD5_T59 0xa3014314 //Transformation Constant 59#define MD5_T61 0xf7537e82 //Transformation Constant 61#define MD5_T62 0xbd3af235 //Transformation Constant 62#define MD5_T63 0x2ad7d2bb //Transformation Constant 63#define MD5_T64 0xeb86d391 //Transformation Constant 64//Null data (except for first BYTE) used to finalise the checksum calculationstatic unsigned char PADDING[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};(2)、CountChecksum.h(md5校验和类的头文件)class CMD5Checksum{public://interface functions for the RSA MD5 calculationstatic CString GetMD5(BYTE* pBuf, UINT nLength);static CString GetMD5(CFile& File);static CString GetMD5(const CString& strFilePath); protected://constructor/destructorCMD5Checksum();virtual ~CMD5Checksum() {};//RSA MD5 implementationvoid Transform(BYTE Block[64]);void Update(BYTE* Input, ULONG nInputLen);CString Final();inline DWORD RotateLeft(DWORD x, int n);inline void FF( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);inline void GG( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);inline void HH( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);inline void II( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);//utility functionsvoid DWordToByte(BYTE* Output, DWORD* Input, UINT nLength); void ByteToDWord(DWORD* Output, BYTE* Input, UINT nLength); private:BYTE m_lpszBuffer[64]; //input bufferULONG m_nCount[2]; //number of bits, modulo 2^64 (lsb first) ULONG m_lMD5[4]; //MD5 checksum};#endif// !defined(AFX_MD5CHECKSUM_H__2BC7928E_4C15_11D3_B2EE_A4A60E20D2C3__INCLUDED_)(3)、CountChecksum.cpp (md5校验和类的实现文件)/*****************************************************************************************FUNCTION: CMD5Checksum::GetMD5DETAILS: static, publicDESCRIPTION: Gets the MD5 checksum for a specified file RETURNS: CString : the hexadecimal MD5 checksum for the specified fileARGUMENTS: CString& strFilePath : the full pathname of the specified fileNOTES: Provides an interface to the CMD5Checksum class. 'strFilePath' name shouldhold the full pathname of the file, eg C:\My Documents\Arcticle.txt.NB. If any problems occur with opening or reading this file,a CFileExceptionwill be thrown; callers of this function should be ready to catch thisexception.*********************************************************** ******************************/CString CMD5Checksum::GetMD5(const CString& strFilePath) {//open the file as a binary file in readonly mode, denying write accessCFile File(strFilePath, CFile::shareDenyNone);//the file has been successfully opened, so now get and return its checksumreturn GetMD5(File);}/********************************************************** *******************************FUNCTION: CMD5Checksum::GetMD5DETAILS: static, publicDESCRIPTION: Gets the MD5 checksum for a specified file RETURNS: CString : the hexadecimal MD5 checksum for thespecified fileARGUMENTS: CFile& File : the specified fileNOTES: Provides an interface to the CMD5Checksum class. 'File' should be open inbinary readonly mode before calling this function.NB. Callers of this function should be ready to catch any CFileExceptionthrown by the CFile functions*********************************************************** ******************************/CString CMD5Checksum::GetMD5(CFile& File){try{CMD5Checksum MD5Checksum; //checksum objectint nLength = 0; //number of bytes read from the file const int nBufferSize = 1024; //checksum the file in blocks of 1024 bytesBYTE Buffer[nBufferSize]; //buffer for data read from the file//checksum the file in blocks of 1024 byteswhile ((nLength = File.Read( Buffer, nBufferSize )) > 0 ){MD5Checksum.Update( Buffer, nLength );}//finalise the checksum and return itreturn MD5Checksum.Final();}//report any file exceptions in debug mode onlycatch (CFileException* e ){TRACE0("CMD5Checksum::GetMD5: CFileException caught"); throw e;}}/********************************************************** *******************************FUNCTION: CMD5Checksum::GetMD5DETAILS: static, publicDESCRIPTION: Gets the MD5 checksum for data in a BYTE array RETURNS: CString : the hexadecimal MD5 checksum for the specified dataARGUMENTS: BYTE* pBuf : pointer to the BYTE arrayUINT nLength : number of BYTEs of data to be checksumed NOTES: Provides an interface to the CMD5Checksum class. Any data that canbe cast to a BYTE array of known length can be checksummed by thisfunction. Typically, CString and char arrays will be checksumed,although this function can be used to check the integrity of any BYTE array.A buffer of zero length can be checksummed; all buffers of zero lengthwill return the same checksum.*********************************************************** ******************************/CString CMD5Checksum::GetMD5(BYTE* pBuf, UINT nLength){//entry invariantsAfxIsValidAddress(pBuf,nLength,FALSE);//calculate and return the checksumCMD5Checksum MD5Checksum;MD5Checksum.Update( pBuf, nLength );return MD5Checksum.Final();}/********************************************************** *******************************FUNCTION: CMD5Checksum::RotateLeftDETAILS: privateDESCRIPTION: Rotates the bits in a 32 bit DWORD left by a specified amountRETURNS: The rotated DWORDARGUMENTS: DWORD x : the value to be rotatedint n : the number of bits to rotate by*********************************************************** ******************************/DWORD CMD5Checksum::RotateLeft(DWORD x, int n){//check that DWORD is 4 bytes long - true in Visual C++ 6 and 32 bit WindowsASSERT( sizeof(x) == 4 );//rotate and return xreturn (x << n) | (x >> (32-n));}/********************************************************** *******************************FUNCTION: CMD5Checksum::FFDETAILS: protectedDESCRIPTION: Implementation of basic MD5 transformation algorithmRETURNS: noneARGUMENTS: DWORD &A, B, C, D : Current (partial) checksum DWORD X : Input dataDWORD S : MD5_SXX Transformation constantDWORD T : MD5_TXX Transformation constant NOTES: None*********************************************************** ******************************/void CMD5Checksum::FF( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T){DWORD F = (B & C) | (~B & D);A += F + X + T;A = RotateLeft(A, S);A += B;}/********************************************************** *******************************FUNCTION: CMD5Checksum::GGDETAILS: protectedDESCRIPTION: Implementation of basic MD5 transformation algorithmRETURNS: noneARGUMENTS: DWORD &A, B, C, D : Current (partial) checksum DWORD X : Input dataDWORD S : MD5_SXX Transformation constantDWORD T : MD5_TXX Transformation constant NOTES: None*********************************************************** ******************************/void CMD5Checksum::GG( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T){DWORD G = (B & D) | (C & ~D);A += G + X + T;A = RotateLeft(A, S);A += B;/********************************************************** *******************************FUNCTION: CMD5Checksum::HHDETAILS: protectedDESCRIPTION: Implementation of basic MD5 transformation algorithmRETURNS: noneARGUMENTS: DWORD &A, B, C, D : Current (partial) checksum DWORD X : Input dataDWORD S : MD5_SXX Transformation constantDWORD T : MD5_TXX Transformation constant NOTES: None*********************************************************** ******************************/void CMD5Checksum::HH( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T){DWORD H = (B ^ C ^ D);A += H + X + T;A = RotateLeft(A, S);A += B;}/********************************************************** *******************************FUNCTION: CMD5Checksum::IIDETAILS: protectedDESCRIPTION: Implementation of basic MD5 transformation algorithmRETURNS: noneARGUMENTS: DWORD &A, B, C, D : Current (partial) checksum DWORD X : Input dataDWORD S : MD5_SXX Transformation constantDWORD T : MD5_TXX Transformation constant NOTES: None*********************************************************** ******************************/void CMD5Checksum::II( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T){DWORD I = (C ^ (B | ~D));A += I + X + T;A = RotateLeft(A, S);A += B;}/********************************************************** *******************************FUNCTION: CMD5Checksum::ByteToDWordDETAILS: privateDESCRIPTION: Transfers the data in an 8 bit array to a 32 bit arrayRETURNS: voidARGUMENTS: DWORD* Output : the 32 bit (unsigned long) destination arrayBYTE* Input : the 8 bit (unsigned char) source array UINT nLength : the number of 8 bit data items in the source arrayNOTES: Four BYTES from the input array are transferred to each DWORD entryof the output array. The first BYTE is transferred to the bits (0-7)of the output DWORD, the second BYTE to bits 8-15 etc. The algorithm assumes that the input array is a multipleof 4 bytes longso that there is a perfect fit into the array of 32 bit words.*********************************************************** ******************************/void CMD5Checksum::ByteToDWord(DWORD* Output, BYTE* Input, UINT nLength){//entry invariantsASSERT( nLength % 4 == 0 );ASSERT( AfxIsValidAddress(Output, nLength/4, TRUE) ); ASSERT( AfxIsValidAddress(Input, nLength, FALSE) );//initialisationsUINT i=0; //index to Output arrayUINT j=0; //index to Input array//transfer the data by shifting and copyingfor ( ; j < nLength; i++, j += 4){Output[i] = (ULONG)Input[j] |(ULONG)Input[j+1] << 8 |(ULONG)Input[j+2] << 16 |(ULONG)Input[j+3] << 24;}}/*****************************************************************************************FUNCTION: CMD5Checksum::TransformDETAILS: protectedDESCRIPTION: MD5 basic transformation algorithm; transforms 'm_lMD5'RETURNS: voidARGUMENTS: BYTE Block[64]NOTES: An MD5 checksum is calculated by four rounds of 'Transformation'.The MD5 checksum currently held in m_lMD5 is merged by the transformation process with data passed in 'Block'.*****************************************************************************************/void CMD5Checksum::Transform(BYTE Block[64]){//initialise local data with current checksumULONG a = m_lMD5[0];ULONG b = m_lMD5[1];ULONG c = m_lMD5[2];ULONG d = m_lMD5[3];//copy BYTES from input 'Block' to an array of ULONGS 'X' ULONG X[16];ByteToDWord( X, Block, 64 );//Perform Round 1 of the transformationFF (a, b, c, d, X[ 0], MD5_S11, MD5_T01);FF (d, a, b, c, X[ 1], MD5_S12, MD5_T02);FF (c, d, a, b, X[ 2], MD5_S13, MD5_T03);FF (b, c, d, a, X[ 3], MD5_S14, MD5_T04);FF (a, b, c, d, X[ 4], MD5_S11, MD5_T05);FF (d, a, b, c, X[ 5], MD5_S12, MD5_T06);FF (c, d, a, b, X[ 6], MD5_S13, MD5_T07);FF (b, c, d, a, X[ 7], MD5_S14, MD5_T08);FF (a, b, c, d, X[ 8], MD5_S11, MD5_T09);FF (d, a, b, c, X[ 9], MD5_S12, MD5_T10);FF (c, d, a, b, X[10], MD5_S13, MD5_T11);FF (b, c, d, a, X[11], MD5_S14, MD5_T12);FF (a, b, c, d, X[12], MD5_S11, MD5_T13);FF (d, a, b, c, X[13], MD5_S12, MD5_T14);FF (c, d, a, b, X[14], MD5_S13, MD5_T15);FF (b, c, d, a, X[15], MD5_S14, MD5_T16);//Perform Round 2 of the transformationGG (d, a, b, c, X[ 6], MD5_S22, MD5_T18); GG (c, d, a, b, X[11], MD5_S23, MD5_T19); GG (b, c, d, a, X[ 0], MD5_S24, MD5_T20); GG (a, b, c, d, X[ 5], MD5_S21, MD5_T21); GG (d, a, b, c, X[10], MD5_S22, MD5_T22); GG (c, d, a, b, X[15], MD5_S23, MD5_T23); GG (b, c, d, a, X[ 4], MD5_S24, MD5_T24); GG (a, b, c, d, X[ 9], MD5_S21, MD5_T25); GG (d, a, b, c, X[14], MD5_S22, MD5_T26); GG (c, d, a, b, X[ 3], MD5_S23, MD5_T27); GG (b, c, d, a, X[ 8], MD5_S24, MD5_T28); GG (a, b, c, d, X[13], MD5_S21, MD5_T29); GG (d, a, b, c, X[ 2], MD5_S22, MD5_T30); GG (c, d, a, b, X[ 7], MD5_S23, MD5_T31); GG (b, c, d, a, X[12], MD5_S24, MD5_T32); //Perform Round 3 of the transformation HH (a, b, c, d, X[ 5], MD5_S31, MD5_T33); HH (d, a, b, c, X[ 8], MD5_S32, MD5_T34); HH (c, d, a, b, X[11], MD5_S33, MD5_T35); HH (b, c, d, a, X[14], MD5_S34, MD5_T36); HH (a, b, c, d, X[ 1], MD5_S31, MD5_T37);HH (c, d, a, b, X[ 7], MD5_S33, MD5_T39); HH (b, c, d, a, X[10], MD5_S34, MD5_T40); HH (a, b, c, d, X[13], MD5_S31, MD5_T41); HH (d, a, b, c, X[ 0], MD5_S32, MD5_T42); HH (c, d, a, b, X[ 3], MD5_S33, MD5_T43); HH (b, c, d, a, X[ 6], MD5_S34, MD5_T44); HH (a, b, c, d, X[ 9], MD5_S31, MD5_T45); HH (d, a, b, c, X[12], MD5_S32, MD5_T46); HH (c, d, a, b, X[15], MD5_S33, MD5_T47); HH (b, c, d, a, X[ 2], MD5_S34, MD5_T48); //Perform Round 4 of the transformationII (a, b, c, d, X[ 0], MD5_S41, MD5_T49); II (d, a, b, c, X[ 7], MD5_S42, MD5_T50); II (c, d, a, b, X[14], MD5_S43, MD5_T51); II (b, c, d, a, X[ 5], MD5_S44, MD5_T52); II (a, b, c, d, X[12], MD5_S41, MD5_T53); II (d, a, b, c, X[ 3], MD5_S42, MD5_T54); II (c, d, a, b, X[10], MD5_S43, MD5_T55); II (b, c, d, a, X[ 1], MD5_S44, MD5_T56); II (a, b, c, d, X[ 8], MD5_S41, MD5_T57); II (d, a, b, c, X[15], MD5_S42, MD5_T58);II (b, c, d, a, X[13], MD5_S44, MD5_T60);II (a, b, c, d, X[ 4], MD5_S41, MD5_T61);II (d, a, b, c, X[11], MD5_S42, MD5_T62);II (c, d, a, b, X[ 2], MD5_S43, MD5_T63);II (b, c, d, a, X[ 9], MD5_S44, MD5_T64);//add the transformed values to the current checksumm_lMD5[0] += a;m_lMD5[1] += b;m_lMD5[2] += c;m_lMD5[3] += d;}/********************************************************** *******************************CONSTRUCTOR: CMD5ChecksumDESCRIPTION: Initialises member dataARGUMENTS: NoneNOTES: None*********************************************************** ******************************/CMD5Checksum::CMD5Checksum(){// zero membersmemset( m_lpszBuffer, 0, 64 );m_nCount[0] = m_nCount[1] = 0;// Load magic state initialization constantsm_lMD5[0] = MD5_INIT_STATE_0;m_lMD5[1] = MD5_INIT_STATE_1;m_lMD5[2] = MD5_INIT_STATE_2;m_lMD5[3] = MD5_INIT_STATE_3;}/********************************************************** *******************************FUNCTION: CMD5Checksum::DWordToByteDETAILS: privateDESCRIPTION: Transfers the data in an 32 bit array to a 8 bit arrayRETURNS: voidARGUMENTS: BYTE* Output : the 8 bit destination arrayDWORD* Input : the 32 bit source arrayUINT nLength : the number of 8 bit data items in the source arrayNOTES: One DWORD from the input array is transferred intofour BYTESin the output array. The first (0-7) bits of the first DWORD aretransferred to the first output BYTE, bits bits 8-15 are transferred fromthe second BYTE etc.The algorithm assumes that the output array is a multiple of 4 bytes longso that there is a perfect fit of 8 bit BYTES into the 32 bit DWORDs.*********************************************************** ******************************/void CMD5Checksum::DWordToByte(BYTE* Output, DWORD* Input, UINT nLength ){//entry invariantsASSERT( nLength % 4 == 0 );ASSERT( AfxIsValidAddress(Output, nLength, TRUE) ); ASSERT( AfxIsValidAddress(Input, nLength/4, FALSE) );//transfer the data by shifting and copyingUINT i = 0;UINT j = 0;for ( ; j < nLength; i++, j += 4){Output[j] = (UCHAR)(Input[i] & 0xff);Output[j+1] = (UCHAR)((Input[i] >> 8) & 0xff);Output[j+2] = (UCHAR)((Input[i] >> 16) & 0xff);Output[j+3] = (UCHAR)((Input[i] >> 24) & 0xff);}}/*****************************************************************************************FUNCTION: CMD5Checksum::FinalDETAILS: protectedDESCRIPTION: Implementation of main MD5 checksum algorithm; ends the checksum calculation.RETURNS: CString : the final hexadecimal MD5 checksum result ARGUMENTS: NoneNOTES: Performs the final MD5 checksum calculation ('Update' does most of the work,this function just finishes the calculation.)*****************************************************************************************/CString CMD5Checksum::Final(){//Save number of bitsBYTE Bits[8];DWordToByte( Bits, m_nCount, 8 );//Pad out to 56 mod 64.UINT nIndex = (UINT)((m_nCount[0] >> 3) & 0x3f);UINT nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex); Update( PADDING, nPadLen );//Append length (before padding)Update( Bits, 8 );//Store final state in 'lpszMD5'const int nMD5Size = 16;unsigned char lpszMD5[ nMD5Size ];DWordToByte( lpszMD5, m_lMD5, nMD5Size );//Convert the hexadecimal checksum to a CStringCString strMD5;for ( int i=0; i < nMD5Size; i++){CString Str;if (lpszMD5[i] == 0) {Str = CString("00");}else if (lpszMD5[i] <= 15) {Str.Format("0%x",lpszMD5[i]);}else {Str.Format("%x",lpszMD5[i]);}ASSERT( Str.GetLength() == 2 );strMD5 += Str;}ASSERT( strMD5.GetLength() == 32 );return strMD5;}/********************************************************** *******************************FUNCTION: CMD5Checksum::UpdateDETAILS: protectedDESCRIPTION: Implementation of main MD5 checksum algorithm RETURNS: voidARGUMENTS: BYTE* Input : input blockUINT nInputLen : length of input blockNOTES: Computes the partial MD5 checksum for 'nInputLen' bytes of data in 'Input'*********************************************************** ******************************/void CMD5Checksum::Update( BYTE* Input, ULONG nInputLen ) {//Compute number of bytes mod 64UINT nIndex = (UINT)((m_nCount[0] >> 3) & 0x3F);//Update number of bitsif ( ( m_nCount[0] += nInputLen << 3 ) < ( nInputLen << 3) ) {m_nCount[1]++;}m_nCount[1] += (nInputLen >> 29);//Transform as many times as possible.UINT i=0;UINT nPartLen = 64 - nIndex;if (nInputLen >= nPartLen){memcpy( &m_lpszBuffer[nIndex], Input, nPartLen );Transform( m_lpszBuffer );for (i = nPartLen; i + 63 < nInputLen; i += 64){Transform( &Input[i] );}nIndex = 0;}else{i = 0;}// Buffer remaining inputmemcpy( &m_lpszBuffer[nIndex], &Input[i], nInputLen-i); }。

相关文档
最新文档