MD5解释

MD5消息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由罗纳德·李维斯特设计,于1992年公开,用以替换MD4算法。MD5在MD4的基础上增加了"安全带"(safety-belts)的概念。虽然MD5比MD4复杂度大一些,但却更为安全。

知识补给:

1、MD4算法需要填补信息以确保信息的比特位长度减去448后能被512整除(信息比特位长度 mod 512 = 448)。然后,一个以64位二进制表示的信息的最初长度被添加进来。信息被处理成512位damgard/merkle迭代结构的区块,而且每个区块要通过三个不同步骤的处理。

2、密码散列函数(Cryptographic hash function),又译为加密散列函数,是散列函数的一种。它被认为是一种单向函数,也就是说极其难以由散列函数输出的结果,回推输入的数据是什么。这样的单向函数被称为“现代密码学的驮马”。

3、散列函数(或散列算法,又称哈希函数,英语:Hash Function)是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合,重新创建一个叫做散列值(hash values,hash codes,hash sums,或hashes)的指纹。散列值通常用一个短的随机字母和数字组成的字符串来代表

4、字节(Byte)是计算机信息技术用于计量存储容量的一种计量单位,也表示一些计算机编程语言中的数据类型和语言字符 。一个字节存储8位无符号数,储存的数值范围为0~255(2^8 - 1)。

Java实现MD5加密

本例中使用了java.security.MessageDigest这个类包来实现加密,实现方法如下:

import java.security.MessageDigest;public class MD5 {public static String Md5(String plainText) {try {//获取MD5消息摘要对象//JDK 6 以上支持以下6种消息摘要算法,不区分大小写// md5,sha(sha-1),md2,sha-256,sha-384,sha-512MessageDigest md = MessageDigest.getInstance("MD5");//通过指定的字节更新摘要md.update(plainText.getBytes("UTF-8"));//获取散列值的字节数组(完成哈希计算)byte b[] = md.digest();int i;StringBuffer buf = new StringBuffer("");for (int offset = 0; offset < b.length; offset++) {i = b[offset];if (i < 0)i += 256;if (i < 16)buf.append("0");//将整数转换成16进制无符号数buf.append(Integer.toHexString(i));}//将无符号整数转成字符串return buf.toString();} catch (Exception e) {//e.printStackTrace();return "";}}}

在此编造一个手机号码进行加密,得到的结果如图所示:

备注:   

本人通过网上MD5在线破解对str1与str2的32位摘要进行破解,发现对于str1,可以很轻易的碰撞出结果,但是对于str2,结果就很难碰撞出。这也得出了,对于手机号的加密,可以通过在手机号前面增加随机字符来增强安全性。该方法在企业中也很常见。

在百度百科中,也指出了MD5的弱点:

1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。2004年,证实MD5算法无法防止碰撞(collision),因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。

知识补给:MD5破解是通过摘要获取原文吗?

答案是否定的,这里所谓的破解,并非把摘要还原成原文。因为固定128位的摘要是有穷的,而原文数量是无穷的,每一个摘要都可以由若干个原文通过Hash得到。对于MD5的破解,实际上都属于【碰撞】。比如原文A通过MD5可以生成摘要M,我们并不需要把M还原成A,只需要找到原文B,生成同样的摘要M即可。即A和B通过MD5加密后的结果殊途同归。

例如:我们用18034587499作为登录密码,后台服务记录的密码为4a05e2a9cbcaa8aea34a0dff645adc55。此时,通过MD5碰撞出一个明文:6666(举例)。我们在登录时就不需要使用18034587499作为登录密码,直接使用6666登录即可骗过应用系统的验签,到达破解密码的效果。

MD5加密原理

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

1、首先需要对信息进行填充,使其字节长度对512求余数的结果等于448。因此,信息的字节长度(Bits Length)将被扩展至N*512+448,即N*64+56个字节(Bytes),N为一个正整数。

2、填充的方法,在信息的后面填充一个1和无数个0,直到满足上面的条件时才停止用0对信息的填充。然后再在这个结果后面附加一个以64位二进制表示的填充前的信息长度。经过这两步的处理,现在的信息字节长度=N*512+448+64=(N+1)*512,即长度恰好是512的整数倍数。这样做的原因是为满足后面处理中对信息长度的要求。

3、四轮循环运算,MD5中有四个32位被称作链接变量(Chaining Variable)的整数参数,他们分别为:A=0x01234567,B=0x89abcdef,C=0xfedcba98,D=0x76543210。当设置好这四个链接变量后,就开始进入算法的四轮循环运算,循环的次数是信息中512位信息分组的数目。

主循环逻辑:
      1、每次操作对a,b,c和d中的其中三个作一次非线性函数运算:F=(b&c)|((~b)&d)
      2、将所得结果加上 第四个变量、一个常数和文本的一个子分组:a+F+K[i]+M[g]
      3、再将所得结果向右环移一个不定的数:shift(a+F+K[i]+M[g],s[i])
      4、并加上a,b,c或d中之一:b = b+shift(a+F+K[i]+M[g],s[i])
      5、最后用该结果取代a,b,c或d中之一:Btemp=b+Btemp

下面将加密原理的代码给出,供学有余力的读者学习。

public class MD5_test {/** 四个链接变量* 为固定值,经过研究所得*/private final int A=0x01234567;private final int B=0x89abcdef;private final int C=0xfedcba98;private final int D=0x76543210;/**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));//右移的时候,高位一定要补零,而不是补充符号位}/**主循环* 1、每次操作对a,b,c和d中的其中三个作一次非线性函数运算:F=(b&c)|((~b)&d)* 2、将所得结果加上 第四个变量、一个常数和文本的一个子分组:a+F+K[i]+M[g]* 3、再将所得结果向右环移一个不定的数:shift(a+F+K[i]+M[g],s[i])* 4、并加上a,b,c或d中之一:b = b+shift(a+F+K[i]+M[g],s[i])* 5、最后用该结果取代a,b,c或d中之一:Btemp=b+Btemp*/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_test instance;public static MD5_test getInstance(){if(instance==null){instance=new MD5_test();}return instance;}private MD5_test(){};public static void main(String[] args){String str=MD5_test.getInstance().getMD5("");System.out.println(str);}
}

有问题可以一起探讨,希望对你有帮助;

我的一小步,填坑一大步!!!

MD5加密算法解释——Java简单应用(java.security.MessageDigest)相关推荐

  1. java简单功能测试,java 自动化测试小功能集锦

    1.  java 调用执行shell 命令 package com.mkyong.shell; import java.io.BufferedReader; import java.io.InputS ...

  2. java 简单万年历,java万年历简单实例

    本文实例讲述了JAVA实现的简单万年历. 实现思路具体如下: 已知1900年1月1日星期一判断是否闰年 指定年月返回当月的天数 返回一年的总天数 返回距离1900年1月到指定年月的上一个月的总天数 实 ...

  3. java记事本简单,java简单完整记事本

    JAVA 程序设计实 验报告 院 系: 信息工程系 专 业: 计算机应用技术 班 级: 11 计算机 01 班 姓 名: Civen 任课教师: XXX 实验题目: JAVA 简单记事本...... ...

  4. 利用Java自带的MD5加密java.security.MessageDigest;

    MD5加密算法,即"Message-Digest Algorithm 5(信息-摘要算法)",它由MD2.MD3.MD4发展而来的一种单向函数算法(也就是HASH算法),它是国际著 ...

  5. MD5加密算法及其在Java中的使用

    MD5算法简介 MD5是不可逆的单向加密算法,因为哈希算法是不可逆的,简单来说,就像我们可以获知5%2=1,3%2=1,7%2=1,但是,当我们仅仅拿到结果1的时候并不知道这是哪个数对2取余得到的结果 ...

  6. MD5加密算法及Java实现

    MD5加密算法及Java实现 上个学期在学数据库的时候,大作业是用Java Web+MySQL实现一个简易的系统,其中老师就提到了MD5算法,用来将用户提交的密码进行加密后放在数据库中,以防被泄露.在 ...

  7. Java中间MD5加密算法完整版

    携带Java软件开发过程.,因此Java中提供了自带的MessageDigest实现对文本的加密算法,以下是一个对文本进行加密的MD5加密工具类代码演示样例: package net.yuerwan. ...

  8. java md5加密32位小写_Java生成MD5的方法,简单封装并转为32位小写

    1 import java.security.MessageDigest; 2 3 public class MD5 { 4 5 public static String toMD5(String p ...

  9. java 和 c md5加密_Java与C++实现同样的MD5加密算法

    1.Java版 package com.lyz.utils.common; import java.io.UnsupportedEncodingException; import java.secur ...

最新文章

  1. 输入输出导入导出问题
  2. ESXi6.5环境搭建(三:vSphere Client6.0安装)
  3. centos下docker1.7 上传文件到容器报错 Error: Path not specified
  4. DNN盛行的当下,老旧的核(kernel)方法或能打开神经网络的魔盒
  5. javascript:history.go()和history.back()的区别
  6. 乐高计算机发展史教程,【乐高产品发展史特别篇】乐高恐龙发展史
  7. java rhino 运行 js_java 脚本引擎Rhino执行js代码和文件
  8. 每日一小练——高速Fibonacci数算法
  9. mysql-cluste多少钱,mysql-cluster集群
  10. python如何实现单例模式_用Python实现设计模式——单例模式
  11. STM32驱动LCD1602程序(调试已成功)
  12. 小米系统shell_廉颇老矣,尚能饭否?小米平板1刷机 lineageOS/CM焕发青春
  13. 计算机安全论文文献,计算机专业毕业论文参考文献
  14. OpenMMLab全景图
  15. 微信公众号图文如何添加PDF附件
  16. 通达oa 修改服务器端口,通达oa云服务器设置
  17. 二维数组的转置,并将其按列和行从小到大排列(Java实现)
  18. Mac OS X 系统清理
  19. 首汽约车驶向极速统一之路!出行平台如何基于StarRocks构建实时数仓?
  20. xp系统计算机蓝屏,xp电脑开机蓝屏代码0×0000000A怎么办

热门文章

  1. 词云python_词语大全
  2. UGUI图片拖拽_保留原图
  3. spark学习之并行度、并发、core数和分区的关系
  4. 11 岁小学生自创“编程语言”,网友:太卷了,后浪都这么厉害了
  5. before和after的用法
  6. html pc端移动端自适应,pc、移动端 自适应布局方案
  7. 计算机组成原理与体系结构——Flynn分类法
  8. YOLOv7环境安装及训练时的一些报错及解决方法
  9. 谷歌 广告营收_初看Google收件箱
  10. 【向生活低头】拷贝文件到文件夹中