MD5是一种我们日常开发中经常使用到的加密方式,它使用起来操作简单且不可逆向解密。那么MD5到底是什么呢?又为什么不可逆呢?下面就来为大家介绍一下MD5加密的原理。
1.什么是MD5加密
MD5消息摘要算法(MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。
MD5加密是一种不可逆的加密算法,不可逆加密算法的特征是加密过程中不需要使用密钥,输入明文后由系统直接经过加密算法处理成密文,这种加密后的数据是无法被解密的,只有重新输入明文,并再次经过同样不可逆的加密算法处理,得到相同的加密密文并被系统重新识别后,才能真正解密
需要注意两点:
1.因为MD5加密得到的结果长度是固定的。所以不论传入字符串长度结果的长度是一样的。
2.当传入的字符串相同的时候经过MD5加密的结果也是一样的。
2.MD5为什么不可解密
MD5不可解密的根本原因是:原文的部分信息是丢失的。通俗的讲,将一段密码截取掉一部分,剩下的那部分,你无法把他还原。
例如:123456789,截取掉中间一部分456,剩下123789。当你在数据库拿到123789这串加密串时,你无法知道原来的密码是多少
3.MD5的破解
2004年,我国科学院院士王小云成功破解了国际上声称根本无解的MD5算法(据说还是一边生孩子、带孩子、做家务一边破解出来的)
她的研究成果表明了给定消息
M1
,能够计算获取 其他的
M2
,使得
M2
产生的散列值与
M1
产生的散列值相同,即:
M1!=M2 && MD5(M1)==MD5(M2)
但是也无需担心,与其说MD5是被“破解”不如说是证实了其“无法防止碰撞”,直到现在,给出一个MD5散列值,然后通过计算还原出原文来是不可能的。也就是说通过一个MD5后的密文,回推明文目前还是没有方法的,目前互联网上的MD5解密网站是将提前用MD5加密出来的大量结果放在数据库中,根据用户输入的匹配结果返回加密前的数据,以此完成解密。
ps:其实MD5必然会出现一个密文对应多个原文的情况,因为MD5生成的密文长度是固定的,而现实世界中的原文是无限的,但之前一直没有能算出与该原文生成相同密文的字符串的方法。
4.什么是盐值
由上文可知,MD5是不可反向破解的,但由于MD5出现已久,互联网上也存在一些通过穷举来实现的MD5解密网站,为了保障用户的信息安全就需要盐值的帮助。
简单来说盐值就是对每个用户生成的一组随机数,在进行MD5加密运算时将盐值和密码共同运算,使相同的密码获得不同的加密结果。运算完成后,将盐值和MD5结果一同存放到数据库中就可以在用户登陆的时候再次运算比较结果。
1、背景:系统通常把用户的密码如MD5加密后,以密文形式保存在数据库中,来防止黑客偷窥。
2、产生:随着对MD5密文查询工具的出现,而很多用户的密码又设置简单,单纯的对用户密码进行MD5加密后保存,用密文很容易就能反查询得到某用户的密码。
3、原理:为用户密码添加Salt值,使得加密的得到的密文更加冷僻,不宜查询。即使黑客有密文查询到的值,也是加了salt值的密码,而非用户设置的密码。salt值是随机生成的一组字符串,可以包括随机的大小写字母、数字、字符,位数可以根据要求而不一样。
4、用途:当用户首次提供密码时(通常是注册时),由系统自动添加随机生成的salt值,然后再散列。而当用户登录时,系统为用户提供的代码撒上同样的加盐值,然后散列,再比较散列值,已确定密码是否正确。
5、其它:经过添加salt值处理的密码,即使用户设置的原密码是相通的,数据库中的密文却是不同的。
5.MD5的使用
下面介绍一下如何在java中使用MD5
1.先导入依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
2.MD5工具类
package com.jd.test;
import org.apache.commons.codec.digest.DigestUtils;
import java.security.MessageDigest;
public class MD5 {
/**
* MD5方法
*
* @param text 明文
* @param key 盐值
* @return 密文
* @throws Exception
*/
public static String md5(String text, String key) throws Exception {
//加密后的字符串
String encodeStr=DigestUtils.md5Hex(text + key);
System.out.println("MD5加密后的字符串为:encodeStr="+encodeStr);
return encodeStr;
}
/**
* MD5验证方法
*
* @param text 明文
* @param key 盐值
* @param md5 密文
* @return true/false
* @throws Exception
*/
public static boolean verify(String text, String key, String md5) throws Exception {
//根据传入的密钥进行验证
String md5Text = md5(text, key);
if(md5Text.equalsIgnoreCase(md5))
{
System.out.println("MD5验证通过");
return true;
}
return false;
}
}
版权归原作者 Pris. 所有, 如有侵权,请联系我们删除。