MD5算法详解

0x00 前言

MD5是一种哈希算法,用来保证信息的完整性。
就一段信息对应一个哈希值,且不能通过哈希值推出这段信息,而且还需要保证不存在任意两段不相同的信息对应同一个哈希值。不过MD5算法算出来的值也就16个字节(16*8=128,即128位),肯定存在相同的,找到另一个所花时间长短而已。

0x01 填充信息

在计算机中,数据存储都是二进制存储的,所以任意一个文件都是些二进制。
每个文件(消息)的大小(长短)都不一样,所以在计算MD5值之前,要将这些文件(消息)用特定内容填充到指定的情况为止。(这里的大小长度是指字节数)

填充的过程如下:
1.先判断文件(消息)的大小(长度) mod 512 == 448 mod 512 ,就是大小(长度)对512求余等于448。(这里的512、448是“位”为单位,转成“字节”就是64、56,即mod 64 == 56 mod 64)

2.如果大小(长度)满足 mod 512 == 448 mod 512,就在文件(消息)的末尾处添加64位(8字节)的值,值的内容是原消息的长度(以位为单位)

3.如果大小(长度)不满足要求,就执行以下操作:
(1)填充1个1
(2)填充0,直到满足满足过程的第一步。
注意:这里是以位为单位,假如是以字节为单位,第一个填充的是0x80(1000 0000),然后就填0x0
举例:消息内容为“gnubd”,就能得到以下内容

67 6E 75 62 64 80 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 28 00 00 00 00 00 00 00 

注意到最后面这里有个0x28,数8个字节,就是0x0000000000000028,刚刚好是十进制的40,消息的内容是5个字节,也就是40位,还要注意到这里是小端字节序存储

0x02 数据说明

填充信息满足要求后就要开始计算MD5值了,首先先把需要的东西先列出来:

DWORD md5::A = 0x67452301;
DWORD md5::B = 0xEFCDAB89;
DWORD md5::C = 0x98BADCFE;
DWORD md5::D = 0x10325476;DWORD md5::T[64] = {0xD76AA478,0xE8C7B756,0x242070DB,0xC1BDCEEE,0xF57C0FAF,0x4787C62A,0xA8304613,0xFD469501,0x698098D8,0x8B44F7AF,0xFFFF5BB1,0x895CD7BE,0x6B901122,0xFD987193,0xA679438E,0x49B40821,0xF61E2562,0xC040B340,0x265E5A51,0xE9B6C7AA,0xD62F105D,0x02441453,0xD8A1E681,0xE7D3FBC8,0x21E1CDE6,0xC33707D6,0xF4D50D87,0x455A14ED,0xA9E3E905,0xFCEFA3F8,0x676F02D9,0x8D2A4C8A,0xFFFA3942,0x8771F681,0x6D9D6122,0xFDE5380C,0xA4BEEA44,0x4BDECFA9,0xF6BB4B60,0xBEBFBC70,0x289B7EC6,0xEAA127FA,0xD4EF3085,0x04881D05,0xD9D4D039,0xE6DB99E5,0x1FA27CF8,0xC4AC5665,0xF4292244,0x432AFF97,0xAB9423A7,0xFC93A039,0x655B59C3,0x8F0CCC92,0xFFEFF47D,0x85845DD1,0x6FA87E4F,0xFE2CE6E0,0xA3014314,0x4E0811A1,0xF7537E82,0xBD3AF235,0x2AD7D2BB,0xEB86D391};DWORD md5::s[64]={7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
};DWORD md5::m[64]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
};

看上去很复杂,其实不是。
首先前4个数值A、B、C、D,它们原本的值是这样的:

A = 0x01234567
B = 0x89ABCDEF
C = 0xFEDCBA89
D = 0x76543210

为了保证ABCD4个值在内存中的显示情况为上面情况,所以要调整数字的位置,故实际情况是:

A = 0x67452301;
B = 0xEFCDAB89;
C = 0x98BADCFE;
D = 0x10325476;

0x03 处理信息

经过信息填充后,填充后的信息长度肯定是512位(64字节)的倍数,也就是说每512位(64字节)为1段可以分成n段,(n大于等于1),对于每一段信息(512位,64字节)又划分成16小段(每段32位,4个字节,用M表示)

对于每一段信息,都会经过下列的运算处理,共4种函数
FF(a,b,c,d,mj,s,ti)
GG(a,b,c,d,mj,s,ti)
HH(a,b,c,d,mj,s,ti)
II(a,b,c,d,mj,s,ti)

对于每种函数都会执行64次
执行顺序是:
先执行16次FF,再执行16次GG,再执行16次HH,最后执行16次II,可以把这个4种函数各执行16次看作一次周期,那么这样的周期有4个,可以简单理解为:

for(i = 0; i < 4; ++i) {FF(16); //括号内为执行次数GG(16);HH(16);II(16);
}

函数的内容分别是:

void md5::FF(DWORD &a,DWORD &b,DWORD &c,DWORD &d,DWORD mj,DWORD s,DWORD ti){DWORD temp = F(b,c,d) + a + mj + ti;temp = (temp<<s)|(temp>>(32-s));a = b + temp; 
}void md5::GG(DWORD &a,DWORD &b,DWORD &c,DWORD &d,DWORD mj,DWORD s,DWORD ti){DWORD temp = G(b,c,d) + a + mj + ti;temp = (temp<<s)|(temp>>(32-s));a = b + temp; 
}void md5::HH(DWORD &a,DWORD &b,DWORD &c,DWORD &d,DWORD mj,DWORD s,DWORD ti){DWORD temp = H(b,c,d) + a + mj + ti;temp = (temp<<s)|(temp>>(32-s));a = b + temp; 
}void md5::II(DWORD &a,DWORD &b,DWORD &c,DWORD &d,DWORD mj,DWORD s,DWORD ti){DWORD temp = I(b,c,d) + a + mj + ti;temp = (temp<<s)|(temp>>(32-s));a = b + temp; 
}

其中,F,G,H,I分别是:

DWORD md5::F(DWORD X,DWORD Y,DWORD Z){return (X&Y)|((~X)&Z);
}DWORD md5::G(DWORD X,DWORD Y,DWORD Z){return (X&Z)|(Y&(~Z));
}DWORD md5::H(DWORD X,DWORD Y,DWORD Z){return X^Y^Z;
}DWORD md5::I(DWORD X,DWORD Y,DWORD Z){return Y^(X|(~Z));
}

接下来是参数说明,由于每个函数的参数具有相同的意义,所以只说一个就行了。
a,b,c,d 4个参数对应的值是周期变化的,周期长度为4,所以是:

for(int j=0;j<16;j+=4){ //每次增加4FF(A,B,C,D,M[m[j]],s[j],T[j]);FF(D,A,B,C,M[m[j+1]],s[j+1],T[j+1]);FF(C,D,A,B,M[m[j+2]],s[j+2],T[j+2]);FF(B,C,D,A,M[m[j+3]],s[j+3],T[j+3]);
}//GG、HH、II也类似,每种函数执行16次(1轮4次,4轮16次)后再执行下一种函数
for(int j=0;j<16;j+=4){GG(A,B,C,D,M[m[j]],s[j],T[j]);GG(D,A,B,C,M[m[j+1]],s[j+1],T[j+1]);GG(C,D,A,B,M[m[j+2]],s[j+2],T[j+2]);GG(B,C,D,A,M[m[j+3]],s[j+3],T[j+3]);
}

M是上面每一段的16个小段了,其中m[j]表示每次函数处理的小段都不同,按照一定的顺序来处理每个小段,其中的顺序就在m中保存了。
s是循环左移的位数,也有一定顺序。
T是常数,共64个,意味着64次的函数调用都是用不同的数值
对于第一段消息(前512位(64个字节))传入的a,b,c,d的值是上面的ABCD4个有规律的值。
第一段消息处理完后(即4个函数各执行了16次之后),得到新的a,b,c,d的值,将它们分别加上原来a,b,c,d的值(即计算前的值),作为下一段消息(第2个512位(64个字节))的初始a,b,c,d的值。

当每段消息(512位,64个字节)都处理完之后,得到的a,b,c,d的值,按照地址的顺序从低到高打印对应的值,就是所求的MD5值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/376346.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我的2015年读书计划,每两周读完一本书!

近日看到一篇文章&#xff0c;说Facebook CEO 马克扎克伯格给自己的2015年定下了一个新的挑战&#xff0c;每两周就要读完一本书&#xff08;传送门&#xff1a;戳这里&#xff09;。想了一下&#xff0c;我自己也很久没看书了&#xff0c;所以今年要改变一下&#xff0c;给自己…

书到用时方恨少

以前觉得的自己的英语还行&#xff0c;四级&#xff0c;六级的什么早就在读书的时候过了&#xff0c; 工作以后&#xff0c;陆陆续续也一直用着英语。 最近发现和老外私下聊天的时候&#xff0c;词汇量严重不足。不明白老外在说什么&#xff0c;一起跟着傻笑。 活到老&#xff…

kettle7.1 右上角不显示connect

kettle7.1右上角不显示connect&#xff0c;就无法使用资源库了。 总结一下解决方法&#xff1a; 1.可能是jdk版本不对&#xff0c;最好使用1.8。原本是10.1&#xff0c;不显示connect&#xff0c;后来装了个1.8后就能显示了。记得是要改环境&#xff0c;javac -version 能显示…

基于XMPP协议的aSmack源码分析

在研究如何实现Pushing功能期间&#xff0c;收集了很多关于Pushing的资料&#xff0c;其中有一个androidnp开源项目用的人比较多&#xff0c;但是由于长时间没有什么人去维护&#xff0c;听说bug的几率挺多的&#xff0c;为了以后自己的产品稳定些&#xff0c;所以就打算自己研…

[Reverse] - 百度杯”CTF比赛 2017 二月场-CrackMe-1

环境&#xff1a;Windows XP 工具&#xff1a; IDA OD EXEINFOPE 0x00 查壳 0x01 分析 拖入OD&#xff0c;字符串查找看一看。 跟进去看就可以知道关键call了 0040196A . 48 dec eax 0040196B . 0F85 C4000000 jnz CrackMe1.00401A35 00401971 . …

【DeepLearning】Exercise:Learning color features with Sparse Autoencoders

Exercise:Learning color features with Sparse Autoencoders 习题链接&#xff1a;Exercise:Learning color features with Sparse Autoencoders sparseAutoencoderLinearCost.m function [cost,grad,features] sparseAutoencoderLinearCost(theta, visibleSize, hiddenSize,…

win7 64位系统下 PL/SQL无法连接的问题

第一步&#xff1a;下载oracle客户端 由于 PLSQL Developer 没有64位版本&#xff0c;所以在64位系统上运行该程链接64位Oracle时就会报错&#xff0c;笔者为这个问题纠结了好几天&#xff0c;后来通过请教Google 动手实践&#xff0c;终于搞定了这个问题。现在把笔者解决的过…

SQL2008R2 express版本不支持维护计划

SQL2008R2 express版本不支持维护计划转载于:https://www.cnblogs.com/toSeeMyDream/p/4218626.html

SHA1算法详解

0x00 前言 SHA1算法也是哈希算法的一种&#xff0c;只要理解了MD5算法&#xff0c;SHA1也很快就能理解。 MD5算法可以参考&#xff1a;MD5算法详解 MD5算法得出的MD5值长度为16个字节&#xff08;8*16128位&#xff09; SHA1算法得出的SHA1值长度为20个字节&#xff08;8*2…

HTML5 地理位置定位(HTML5 Geolocation)

地理位置&#xff08;Geolocation&#xff09;是 HTML5 的重要特性之一&#xff0c;提供了确定用户位置的功能&#xff0c;借助这个特性能够开发基于位置信息的应用。今天这篇文章向大家介绍一下HTML5 地理位置定位的基本原理及各个浏览器的数据精度情况。 在访问位置信息前&a…

2016腾讯安全挑战赛第一轮-PC游戏方向

0x00 查壳 无壳的VC程序 0x01 测试 没有消息弹窗&#xff0c;尝试对函数下断点。 OD载入后&#xff0c;CtrlN查找函数&#xff0c;找到GetDlgItem 程序运行起来&#xff0c;等输入完后点击确定后程序断下。一路F8就来到这里 00401EED . E8 6A5B0000 call Tenc…

49-今日交易总结.(2015.1.13)

49-今日交易总结今天交易情况不好&#xff0c;主要犯了亏损时还连续加仓的错误。作为一个交易者&#xff0c;亏损时&#xff0c;继续加仓&#xff0c;认为市场会向交易的方向变化&#xff0c;一次性把亏损的全部捞回来&#xff0c;还能赚一笔。这是一种赌徒心理。永远不要再亏损…

电商导购过冬:蘑菇街酝酿出售 美丽说转型时尚

一度红火的第三方导购网站正因为阿里巴巴过山车式的态度而呈现出急剧下滑的轨迹。 2011年&#xff0c;以美丽说、蘑菇街为代表的导购网站蜂拥而起。彼时&#xff0c;两者还能频繁出现在阿里巴巴的官方活动中。然而&#xff0c;2012年5月&#xff0c;阿里巴巴集团董事局主席马云…

JavascriptDOM(三)

简介 今天学习第二天的知识,js和BOM对象,再接再厉,fighting~学习原则 脚踏实地的走好每一步,要想学好高级部分,基础知识必须扎实呀 掌握基本语法,完成小案例,写博客作总结,基本就是这个节奏,下面我们一起快速入门吧JavaScript快速入门 1. js简介 1.js基于对象和事件驱动的脚本语…

看雪 2016CrackMe 攻防大赛 - 1-Crack_Me-凉飕飕

环境&#xff1a; Windows xp 工具&#xff1a; IDA EXEINFOPE OD 0x00 查壳 EXEINFOPE查壳&#xff0c; 无壳 0x01 分析 if ( (unsigned __int16)wParam 0x40B ) // 成功{*(_OWORD *)v22 xmmword_41DB98;v25 0;v23 xmmword_41DBA8;v24 xmmword_41DBB8;memset_4039D0…

JS 或css教程 识别 IE版本的几种方法

今天收藏了这几种关于识别ie版本的几种代码&#xff0c;有需要的朋友参考一下&#xff1a;var isIE!!window.ActiveXObject;var isIE6isIE&&!window.XMLHttpRequest;var isIE8isIE&&!!document.documentMode;var isIE7isIE&&!isIE6&&!isIE8;if…

使用CSDN-markdown编辑器

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…

C++ vector类详解

转自http://blog.csdn.net/whz_zb/article/details/6827999 vector简介 vector是STL中最常见的容器&#xff0c;它是一种顺序容器&#xff0c;支持随机访问。vector是一块连续分配的内存&#xff0c;从数据安排的角度来讲&#xff0c;和数组极其相似&#xff0c;不同的地方就是…

ViewPager的使用方法和实现过程

看图先&#xff1a; 页面中填充内容是随机关键词飞入和飞出动画效果&#xff0c;随后会更新&#xff0c;现在请先无视吧 首先是 导入jar包 下载地址&#xff1a; android-support-v4.jar 布局文件里添加viewPager布局 [html] view plaincopyprint?<android.support.v4.vi…

如何通过浏览器在所有响应内容中查找文本

使用浏览器的开发者工具查找响应文件的内容 ** Chrome ** 版本&#xff1a; 快捷键&#xff1a;CtrlShiftF 可以看到已经查找出来了 ** firefox ** 版本