MD5 加密算法详解
MD5 加密算法详解
- 一、概念
- 二、算法原理
- 2.1、MD5(32)、MD5(16)
- 2.2、算法 4步流程
- 三、 其他
- 3.1、作用
- 3.2、MD5可以作为数据库主键,唯一吗?
- 3.3、测试源码
一、概念
MD5算法是单向散列算法的一种。单向散列算法也称为HASH算法,是一种将任意长度的信息压缩至某一固定长度(称之为消息摘要)的函数(该压缩过程不可逆)。在MD5算法中,这个摘要是指将任意数据映射成一个128位长的摘要信息。并且其是不可逆的,即从摘要信息无法反向推演中原文,在演算过程中,原文的内容也是有丢失的。
并非说md5不能破解。MD5破解可以参考王晓云教授的《MD5破解》论文
因为MD5算法最终生成的是一个128位长的数据,从原理上说,有2^128种可能,这是一个非常巨大的数据,约等于3.4乘10的38次方,虽然这个是个天文数字,但是世界上可以进行加密的数据原则上说是无限的,因此是可能存在不同的内容经过MD5加密后得到同样的摘要信息,但这个碰中的概率非常小。可用于数字签名、信息完整性检查等用途;
1、对于需要高度安全性的数据,一般改用其他算法,如SHA-2。MD5算法无法防止碰撞(collision),因此不适用于安全性认证,如SSL公开密钥认证或是高要求的数字签名等用途。
2、常见的散列算法还有SHA、RIPE-MD、HAVAL、N-Hash等
二、算法原理
2.1、MD5(32)、MD5(16)
MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。
将这128 位用十六进制表示便是常见的32 字符的MD5 码,而所谓的16 字符的MD5 码,其实是这32 字符中间的16 个字符。
MD5(123456,32) = e10adc3949ba59abbe56e057f20f883e
MD5(123456,16) = 49ba59abbe56e057
2.2、算法 4步流程
MD5 算法将输入的信息进行分组,每组512 位(64个 字节),顺序处理完所有分组后输出128 位结果。
在每一组消息的处理中,都要进行4 轮、每轮16 步、总计64 步的处理。其中每步计算中含一次左循环移位,每一步结束时将计算结果进行一次右循环移位。详见下方流程。
第1步:进行数据填充整理
这一步是对要加密的数据进行填充和整理,将要加密的二进制数据对512取模,得到的结果如果不够448位,则进行补足,补足的方式是第1位填充1,后面全部填充0。
为啥是448位呢? 在数据读取时,会有一个结束标识位。如同c中的字符串,有一个\0的结束标识;
将需加密的信件信息(如一份文件)分次读取到缓冲区中,一次最好读取64*n 个字节,这样就是n 组,方便处理。那么此时,对信息进行填充,使其字节数除以64 时余数为56,其一个结束标识符就是8字节;如,一个消息为64n 倍数字节,则最后一次读取0 字节(结束标识),据本规则将填充56 字节(448bit)。
第2步:记录数据长度
经过第一步整理完成后的数据的位数可以表示为N*512+448,再向其后追加64位用来存储数据的长度,比如数据的长度为16字节,则用10000来填充后64位。这一步做完后,数据的位数将变成(N+1)*512。
第3步:以标准的幻数作为输入
MD5的实现需要每512个字节进行一次处理,后一次处理的输入为前一次处理的输出,因此,在循环处理开始之前,需要拿4个标准数作为输入,它们分别是:
unsigned int A=0x67452301,B=0xefcdab89,C=0x98badcfe,D=0x10325476;
第4步:进行N轮循环处理,将最后的结果输出
这一步重要的是每一轮的处理算法,每一轮处理也要循环64次,这64次循环被分为4各组,每16次循环为一组,每组循环使用不同的逻辑处理函数,处理完成后,将输出作为输入进入下一轮循环。
通过上面的标准128bit 输入,参与每组512bit 计算,得到一个新的128值,接着参与下一轮循环运算,最终得到一个128位的值;
具体运算:
这里用到4 个逻辑函数F,G,H,I,分别对应4 轮运算,它们将参与运算。(4轮16步)
第一轮逻辑函数:F(b,c,d)=(b&c)|((~b)&d) 参与第一轮的16 步运算 (b,c,d均为32位数)
第二轮逻辑函数:G(b,c,d)=(b&d)|(c&(~d)) 参与第二轮的16 步运算
第三轮逻辑函数:H(b,c,d)= bcd 参与第三轮的16 步运算
第四轮逻辑函数:I(b,c,d)= c^(b|(~d)) 参与第四轮的16 步运算
再引入一个移位函数MOVE(X,n),它将整型变量X 左循环移n 位,如变量X 为32 位,则MOVE(X,n)= (X
<< n) | (X >> (32 - n))。
三、 其他
3.1、作用
- 一致性检验,如大文件上传时,需要对文件一致性校验;
- 数字签名,还是最上面那个例子。只是把md5看出了一个指纹,按了个手印说明独一无二了;
- 安全访问认证等;
如:在用户注册时,会将密码进行md5加密,存到数据库中。这样可以防止那些可以看到数据库数据的人,恶意操作了。
3.2、MD5可以作为数据库主键,唯一吗?
前面也讲了md5无法避免碰撞,那么md5值就不唯一。
也就是一个原始数据,只对应一个md5值;但是一个md5值,可能对应多个原始数据。
3.3、测试源码
package com.xuecheng.test.md5test;import org.springframework.util.DigestUtils;public class MD5 {/**四个链接变量*/private final int A=0x67452301;private final int B=0xefcdab89;private final int C=0x98badcfe;private final int D=0x10325476;/**ABCD的临时变量*/private int Atemp,Btemp,Ctemp,Dtemp;/**常量ti*公式:floor(abs(sin(i+1))×(2pow32)*/private final int K[]={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};/**向左位移数,计算方法未知*/private final int s[]={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};/**初始化函数*/private void init(){Atemp=A;Btemp=B;Ctemp=C;Dtemp=D;}/**移动一定位数*/private int shift(int a,int s){return(a<<s)|(a>>>(32-s));//右移的时候,高位一定要补零,而不是补充符号位}/**主循环*/private void MainLoop(int M[]){int F,g;int a=Atemp;int b=Btemp;int c=Ctemp;int d=Dtemp;for(int i = 0; i < 64; 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;}else{F=c^(b|(~d));g=(7*i)%16;}int tmp=d;d=c;c=b;b=b+shift(a+F+K[i]+M[g],s[i]);a=tmp;}Atemp=a+Atemp;Btemp=b+Btemp;Ctemp=c+Ctemp;Dtemp=d+Dtemp;}/**填充函数*处理后应满足bits≡448(mod512),字节就是bytes≡56(mode64)*填充方式为先加一个0,其它位补零*最后加上64位的原来长度*/private int[] add(String str){int num=((str.length()+8)/64)+1;//以512位,64个字节为一组int strByte[]=new int[num*16];//64/4=16,所以有16个整数for(int i=0;i<num*16;i++){//全部初始化0strByte[i]=0;}int i;for(i=0;i<str.length();i++){strByte[i>>2]|=str.charAt(i)<<((i%4)*8);//一个整数存储四个字节,小端序}strByte[i>>2]|=0x80<<((i%4)*8);//尾部添加1/**添加原长度,长度指位的长度,所以要乘8,然后是小端序,所以放在倒数第二个,这里长度只用了32位*/strByte[num*16-2]=str.length()*8;return strByte;}/**调用函数*/public String getMD5(String source){init();int strByte[]=add(source);for(int i=0;i<strByte.length/16;i++){int num[]=new int[16];for(int j=0;j<16;j++){num[j]=strByte[i*16+j];}MainLoop(num);}return changeHex(Atemp)+changeHex(Btemp)+changeHex(Ctemp)+changeHex(Dtemp);}/**整数变成16进制字符串*/private String changeHex(int a){String str="";for(int i=0;i<4;i++){str+=String.format("%2s", Integer.toHexString(((a>>i*8)%(1<<8))&0xff)).replace(' ', '0');}return str;}/**单例*/private static MD5 instance;public static MD5 getInstance(){if(instance==null){instance=new MD5();}return instance;}private MD5(){};public static void main(String[] args){String str=MD5.getInstance().getMD5("123");System.out.println(str);String s1 = DigestUtils.md5DigestAsHex("123".getBytes());System.out.println(s1);}}
参考资料
https://cloud.tencent.com/developer/article/1402024
https://my.oschina.net/u/3352105/blog/875927
https://www.cnblogs.com/orangebook/p/3558334.html
MD5 加密算法详解相关推荐
- 密码学:RSA加密算法详解
概述 本文旨在说明RSA加密算法的原理及实现,而其相关的数学部分的证明则不是本文内容. 版权说明 著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:Q-WHai 发表日期: ...
- MD5算法详解及实现(C语言)
其他现代密码学算法详解及实现见专栏合集~ MD5算法 算法过程 (i)消息填充 首先填充消息,使它的长度比512的整数倍少64位(这64位用来记录原数据长度).填充的内容由一个1和后续的0组成.必须进 ...
- openssl_sign() 语法+RSA公私钥加密解密,非对称加密算法详解
其实有时候觉得写博客好烦,就个函数就开篇博客.很小的意见事情而已,知道的人看来多取一举,或者说没什么必要,浪费时间,不知道的人就会很郁闷.技术就是这样的,懂的人觉得真的很简单啊,不知道的人真的好难.. ...
- java的rsa加密_java实现的RSA加密算法详解
本文实例讲述了java实现的RSA加密算法.分享给大家供大家参考,具体如下: 一.什么是非对称加密 1.加密的密钥与加密的密钥不相同,这样的加密算法称之为非对称加密 2.密钥分为:公钥,私钥 公钥:可 ...
- RSA加密算法详解及例题
这是我自己在学习RSA加密算法的时候自己整理的笔记,如需转载请注明出处 RSA加密算法 我这里就不对RSA的发明背景做介绍了,你只要知道RSA加密算法是非常非常重要的加密算法,放在现在的时代亦是如此. ...
- rsa加密算法java实例,java实现的RSA加密算法详解
本文实例讲述了java实现的RSA加密算法.分享给大家供大家参考,具体如下: 一.什么是非对称加密 1.加密的密钥与加密的密钥不相同,这样的加密算法称之为非对称加密 2.密钥分为:公钥,私钥 公钥:可 ...
- RSA加密算法详解以及RSA在laravel中的应用
最近做APP,由于刚开始开发,所以关于数据传输之间的加密部分还没做.在BOSS的要求下,准备给APP的接口加上RSA加密.先测试一个小demo. 一.使用场景 APP接口数据部分的加密.特别是设计到账 ...
- c# php加解密,PHP和C#可共用的可逆加密算法详解
在一些项目中要求在php中生成加密,然后在asp.net中接受过来的密码再解密,下面和大家分享一个PHP与asp.net C#可共用的可逆加密算法,感兴趣的可以参考参考. php加密算法: class ...
- oracle解析md5,Oracle中的MD5加密详解
一.技术点 1. DBMS_OBFUSCATION_TOOLKIT.MD5 DBMS_OBFUSCATION_TOOLKIT.MD5是MD5编码的数据包函数,但偶在使用select DBMS_OBFU ...
- php的md5(),php MD5加密详解
PHP crypt()函数可以完成基本的加密功能: string crypt (string input_string [, string salt]) 这一函数完成被称作单向加密的功能,也就是说,它 ...
最新文章
- Task03:青少年软件编程(Scratch)等级考试模拟卷(二级)
- python简单计算器异常处理_Python实现的简单计算器
- 小程序 数据缓存
- BETA、RC、ALPHA、Release、GA 等版本号的意义
- Java技术:SpringBoot实现邮件发送功能
- 在编码中熟练使用JDK文档
- matlab创建nc文件怎么打开,MATLAB打开nc文件并读取nc文件数据
- CNN提取文本特征,融合PMF模型实现推荐系统
- 苹果Safari中保存的密码如何导入Chrome浏览器?
- 神经网络的直观解释相关文档
- 线性代数学习之坐标转换和线性变换
- 30分钟一部动画短片!从MMD入门3D世界,边玩边学的3D教程!(一)“MMD快速入门教程CSDN”
- 电路交换、报文交换、分组交换各自的特点
- 公司计算机程序员英语怎么说,计算机程序员英文求职信范文模板
- 记录一下学习EFCore中的基础知识
- 假如明天失业了,我该去哪里
- 《东周列国志》第八十五回 乐羊子怒啜中山羹 西门豹乔送河伯妇
- 支付宝网商贷是雪中送炭么?
- 腾讯会议发布录屏工具“会记”,让云端视频协作随用随录、随享随看
- 解决openwrt opkg内核版本不匹配问题
热门文章
- SQL Server 2008安装图解教程
- python可以破解网站吗_python变相破解校园网 - 『编程语言区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn...
- 人工神经网络的算法原理,人工神经网络算法步骤
- 怎么将几张pdf合并成一张_如何将多个PDF合并成一个PDF?PDF文档合并成单个的方法...
- 深度学习与计算机视觉教程(8) | 常见深度学习框架介绍(CV通关指南·完结)
- ug二次开发python_UG/NX二次开发入门指导
- 3DMAX卸载/完美解决安装失败/如何彻底卸载清除干净3DMAX各种残留注册表和文件的方法
- yum安装wget命令
- C语言全局变量和数组的应用
- 详解Java 堆排序