发布日期:2023-07-24
本章将介绍通过eLinx(2.1.5版本)软件实现MD5(英文:MD5 Message-Digest Algorithm )不可逆校验算法。内容主要包括:ROM的基本使用、MD5原理理解、Verilog语法理解。
通过本章的阅读,读者将会完全掌握对MD5原理及算法编写的流程,并体会到Verilog是一款对位拼接极强的语言。
1、前言
散列函数是用以提供消息的完整性保护,是计算机广泛使用的哈希算法之一,常常应用于账号登陆密码保护、文件包检验、数字签名、云盘秒传、大型文件数据传输、安全访问认证、、登录认证、指纹解锁、撞库。之所以可以广泛使用不得不提到MD5的性质:压缩性、容易计算、抗修改性、弱抗碰撞、弱抗碰撞。
举例:当我们在网络上下载文件时,如果想知道下载的这个文件和网站的原始文件是否一样,就可以给自己下载的文件做个MD5校验。如果得到的MD5值和网站公布的相同,可确认所下载的文件是完整的。如有不同,说明下载的文件是恶意被他人篡改过是不完整的而且很有可能带有病毒。
2、MD5概述
MD5就是把一串字符串转成512固定的bit(64字节),一个字节的长度是8bit,我们先将数据包分割成每64字节为一个分组,这样可以被分割成N512+R,我们对R进行补位,让它变成512位(第一位补1,后面全部补0)。
1)填充:如果输入信息的长度(bit)对512求余的结果不等于448,就需要填充使得对512求余的结果等于448。填充的方法是填充一个1和n个0。填充完后,信息的长度就为N512+448(bit);
2)记录信息长度:用64位来存储填充前信息长度。这64位加在第一步结果的后面,这样信息长度就变为N512+448+64=(N+1)512位;
3)装入标准的幻数(四个整数):标准的幻数(物理顺序)是(A=(01234567)16,B=(89ABCDEF)16,C=(FEDCBA98)16,D=(76543210)16)。如果在程序中定义应该是(A=0X67452301L,B=0XEFCDAB89L,C=0X98BADCFEL,D=0X10325476L);
4)四轮循环运算:循环的次数是分组的个数(N+1)。如图2-1
图 2‑1
3、计算概述
原始数据【123456】------>转换ascii码【313233343536】
1)第一步:数据填充对原始ascii数据进行数据填充,使消息的长度对512取模得448(如果不满足则需要填充0)。根据此公式得出需要填充的数据长度。填充方法:在消息后面进行填充,填充第一位为1,其余为0。填充完后,信息的长度就是512N+448。之后,用剩余的位置(512-448=64位)记录原文的真正长度,把长度的二进制值补在最后。这样处理后的信息长度就是512(N+1)。其中6字节为数据,1字节与49字节是补充位,最后8字节为数据长度位。如图3-1。
图 3‑1
2)第二部:大小端互换,此数据进入MD5校验无法得到正确的值,在进入校验前需要每32bit进行大小端互换。而数据长度则需要每32bit交换位置即可。将此64个字节输入MD5算法即可得到对应十进制【123456】的32字节的校验值。如图3-2。
图 3‑2
3)第三步:设置初始值MD5的哈希结果长度为128位,按每32位分成一组共4组。这4组结果是由4个初始值A、B、C、D经过不断演变得到。MD5的官方实现中,A、B、C、D的初始值如下(16进制):
A=0x01234567
B=0x89ABCDEF
C=0xFEDCBA98
D=0x76543210
4)第四步:循环加工A,B,C,D就是哈希值的四个分组。每一次循环都会让旧的ABCD产生新的ABCD。一共进行多少次循环呢?由处理后的原文长度决定。假设处理后的原文长度是M,主循环次数=M/512,每个主循环中包含512/324=64次子循环。
在第一步中,处理后原文的长度是512的整数倍。把原文的每512位再分成16等份,命名为M0M15,每一等份长度32。在64次子循环中,每16次循环,都会交替用到M1M16之一。
Ki一个常量,在64次子循环中,每一次用到的常量都是不同的。如图3-3
图 3‑3
4、程序设计
ROM存储需要进行MD5校验的十进制数据,从ROM中读取需要的数据进入ASCII转换模块(Octal_transformation)从中将十进制数据转换成ASCII的同时提取十进制数据的个位十位百位进行计数,在转换的同时也将8位的数据进行拼接与大小端互换处理模块(data_md5),因数据长度可知每8字节大小端进行互换,需要补位的0过计算得取公式64x2- n可得需要补的0的个数,但需要注意表示长度的数据不进行大小互换需每4字节调换位置,全部处理完成bit将拼接完成的32bit数据继续拼接成512bit数据模块(data_dispose)送入MD5校验模块(correct),MD5算法部分可参考【计算概述】。
程序框架如图4-1所示:
图 4‑1
顶层模块的原理图如图4-2所示:
图 4‑2
顶层模块部分代码如图4-3所示:
图 4‑3
ROM中存储数据格式如图4-4所示:
图 4‑4
大小端相互转换如图4-5所示:
图 4‑5
Correct模块主要工作是为了将最后一包MD5数据的最后64bit数据每32bit进行交换。(因为最后一包数据的64bit是数据长度根据算法要求进行操作)
test2模块代码如图4-6所示:
图 4-6
请求数据信号有效,将ROM内部地址添加1将数据与使能信号一并输出。(因为转换时间过长所以必须采用缓存器)
Octal_transformation模块代码如图4-7所示:
在代码47-194行中,执行请求数据与数据转换完成后的发送,在76-99行中,如果超过1000个周期无输入的数据响应则表示数据全部转换完成,可以通知其他模块进行补位0的操作,在100-134行中提取十进制数据位数,如果该数据小于9则表示只有1位,大于9小于100表示只有2位数据以此类推同时LEN信号作为位数的计数器,在135-191中将十进制数据转换后的ASCII码发送用做数据拼接使用。
中间省略
图 4-7
在代码196-499行中,采用了查找表进行十进制与ASCII直接的快速互换,可以在一周期内完成转换,如数据量巨大可以有效节省时间。
data_md5模块代码如下图4-8所示:(较为复杂请仔细阅读代码介绍)
第62-67行place_LENGTH信号负责计算ascii的个位数,用作于防止在MD5数据长度中。在96-103行中计算不同输入数据长度的补位0数,因输入大于64字节与小于64字节最终计算的补位是不一样的特此分开计算。代码142-227拼接数据,记录数据当前拼接长度保证在下次数据到来后能与上一次数据拼接。代码228-262行中等待计算需要补位的0与它需要补在什么位置。程序264-287行中对80进行拼接,而在290-345行则对0进行拼接(至于拼接多少个0稍后有详细介绍)。代码346-361行对数据长度进行拼接。
中间省略
代码373-397行针对输入数据长度小于64字节进行计算,choose信号在399-487行中为,通过公式64x2- n可得需要拼接的0数,得到结果data_2是有符号数据所以如果64x2小于n则最高位为1反之则为0,使用差值进行拼接0位操作。
中间省略
图 4-8
代码490-562行中是对大于64字节进行,在495-549中与小于64字节选值一样,也是不同的地方也是此处的重点,551-559行如图4-9与如图4-10中有详细介绍在剩余的9字节中抛出8字节的数据长度与1个字节的80与1个字节的00,则还少1个字节的位置,就需要再次添加一包MD5数据格式如图4-11。
图 4-9
图 4-10
图 4-11
data_dispose模块代码如下图4-12所示:
图 4-12
代码43-77行中对MD5最后一包数据进行了判断,在最后一包数据到来前即使相应进行数据长度每32bit的交换处理。97-111行中对数据的大小端进行交换(如何交换前面有介绍过)。113-155行中对512bit数据进行拼接。x
correct模块代码如下图4-13所示:
图 4-13
只为了修正MD5编码的最后64bit,再次大小端互换(相应data_dispose模块),并且每32bit进行交换。
核心算法MD5介绍“RTL视图”如下图4-14所示:
图 4-14
由两个模块组成MD5校验核心算法与最终MD5输出128bit数值进行处理与转换显示。
程序略
abcd的初始值:{a<=32h67452301;b<=32hefcdab89;c<=32h98badcfe;d<=32h10325476;}消息分以512位为一分组进行处理,每一个分组进行4轮共64次计算后将A,B,C,D分别加上计算得到的a,b,c,d当作新的A,B,C,D,并将这4个变量赋值给a,b,c,d再进行下一分组的运算 此时abcd的值为上次计算的结果{a<=a_0,b<=b_0,c<=c_0,d<=d_0}由于填充后的消息长度为(N+1)512,则共需计算N+1个分组。计算所有数据分组后,这4个变量为最后的结果,即MD5值。
size模块代码:将MD5计算完成后的128bit数据处理成于校验相同的结果。如4-15图所示:
图 4-15
如需获取MD5核心算法请于亿海微官网联络(联络方式:技术支持社区https://www.ehiway.cn/dl/1dU1aHvdPE.html)
5、仿真验证:
1)原始数据:
127151175197216232244251254251244232216197175151127102785637219202921375678102
2)进入ascii转换如图5-1所示:
图 5-1
3)将8bit数据拼接成32bit数据如图5-2所示:
图 5-2
4)进行大小端互换于MD5数据格式拼接如图5-3所示:
图 5-3
5)将最后一包数据的长度每32bit进行交换如图5-4所示:
图 5-4
6)进行算法验证即可如图5-5所示:
图 5-5
总结: FPGA的计算速度快,加密速度快,发送方给予一段128bit密钥即可,就可以检查文件的完整性,一旦文件被更改,MD5值会改变从而导致计算后的值与密钥不匹配,从而防止文件被篡改。(在大型文件传输中,MD5没有缺点)
文献参考: MD5百度百科
https://baike.baidu.com/item/MD5/212708#%E5%8F%91%E5%B1%95%E5%8E%86%E5%8F%B2
文献参考:中华人民共和国国家知识产权局 发明名称:一种基于MD5算法的加密算法
https://wenku.baidu.com/view/3dce6e0148fe04a1b0717fd5360cba1aa9118c21?_wkts_=1686646038891