写在文章之前
1.源码路径:https://github.com/liangminghui/MavenDemo.git 如果没有git环境,可以用zip包下载
2.本文章演示案例均为maven案例,需要引入下边这个包
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
加密相关
最简单的MD5加密
@Test
public void test1() {
String test_str_first = 11316 + "";
System.out.println(getMD5(test_str_first));
}
/**
* 对字符串md5加密(小写+字母)
*
* @param str 传入要加密的字符串
* @return MD5加密后的字符串
*/
private String getMD5(String str) {
return DigestUtils.md5Hex(str);
}
最简单的揭秘方法就是访问这个网站 https://www.cmd5.com/ 把加密出来的数据解密,如下所示
常用复杂加密MD5方法
多次加密
@Test
public void test2() {
String test_str_first = 11316 + "";
String salt = "666";
// 1 :多次加密
System.out.println(getMD5(test_str_first, 2));
//2 : 加盐
//2.1 密码加盐
// System.out.println(getMD5(test_str_first+salt));
//2.2 加密之后加盐
// System.out.println(getMD5(test_str_first,salt));
}
private String getMD5(String str, int count) {
if (count == 0) {
return str;
} else {
str = getMD5(str);
return getMD5(str, count - 1);
}
}
虽然这个方式看起来很可靠,但是很不幸,上边所用的网站也可以破解这个密码,如图
不仅能解密,还能显示加密多少次。。。所以现在很多程序都在使用加盐的方式
加盐
首先解释一下什么叫做加盐,类似于做菜一样,是在原加密的基础上,加上一段“标记”,混淆密码,代码如下所示
1.先加盐再加密
@Test
public void test2() {
String test_str_first = 11316 + "";
String salt = "666";
// 1 :多次加密
//System.out.println(getMD5(test_str_first, 2));
//2 : 加盐
//2.1 密码加盐
System.out.println(getMD5(test_str_first+salt));
//2.2 加密之后加盐
// System.out.println(getMD5(test_str_first,salt));
}
这种加密虽然不失为一个解决方法,但是解密出来之后即使加盐,原密码也是有暴漏的风险
2.先加密在加盐
@Test
public void test2() {
String test_str_first = 11316 + "";
String salt = "666";
// 1 :多次加密
//System.out.println(getMD5(test_str_first, 2));
//2 : 加盐
//2.1 密码加盐
//System.out.println(getMD5(test_str_first+salt));
//2.2 加密之后加盐
System.out.println(getMD5(test_str_first,salt));
}
private String getMD5(String str,String salt) {
try {
// 生成一个MD5加密计算摘要
MessageDigest md = MessageDigest.getInstance("MD5");
// 计算md5函数
md.update(str.getBytes());
// digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
// BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
return new BigInteger(1, md.digest()).toString(16)+salt;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
众所周知,MD5加密出来的数据是有固定长度的。现在就算获取到了“3798003c3d078a7b4fd1f33843a2e5c0666”这个值,除非知道加密方式以及盐值,否则很难解密出原文,所以这种方式应用广泛。
碰撞
什么叫碰撞?简单的来说就是加密出来的值相同,现在简单写个案例,重现一下碰撞,代码如下,在运行代码之前,你需要下载如下两个EXE文件(这两个文件不可安装,只是两个在文件加密之后值相同,下载之后给个star吧)
@Test
public void test3(){
String path = "F:\\project\\MavenDemo\\src\\test\\java\\demo\\";
try {
String str1 = DigestUtils.md5Hex(new FileInputStream(path+"GoodbyeWorld-colliding.exe"));
String str2 = DigestUtils.md5Hex(new FileInputStream(path+"HelloWorld-colliding.exe"));
String str1_sha = DigestUtils.sha1Hex(path+"GoodbyeWorld-colliding.exe");
String str2_sha = DigestUtils.sha1Hex(path+"HelloWorld-colliding.exe");
System.out.println("str1 md5>>>>>"+str1);
System.out.println("str2 md5>>>>>"+str2);
// System.out.println("str1_sha>>>>>"+str1_sha);
// System.out.println("str1_sha>>>>>"+str2_sha);
// System.out.println(DigestUtils.md5Hex(str1+str1_sha));
// System.out.println(DigestUtils.md5Hex(str2+str2_sha));
}catch (Exception e){
System.out.println(e);
}
}
关于碰撞有以下几点
1.怎样解决碰撞
解决碰撞其实可以通过 MD5 和 SHA-1 结合使用来实现。首先将文件 A 的 MD5 值记为 B 再把 A 的 SHA-1 记为 C,之后用将 B 和 C 相加之后再次运算 MD5 值
@Test
public void test3(){
String path = "D:\\project\\MavenDemo\\src\\test\\java\\demo\\";
try {
String str1 = DigestUtils.md5Hex(new FileInputStream(path+"GoodbyeWorld-colliding.exe"));
String str2 = DigestUtils.md5Hex(new FileInputStream(path+"HelloWorld-colliding.exe"));
String str1_sha = DigestUtils.sha1Hex(path+"GoodbyeWorld-colliding.exe");
String str2_sha = DigestUtils.sha1Hex(path+"HelloWorld-colliding.exe");
System.out.println(DigestUtils.md5Hex(str1+str1_sha));
System.out.println(DigestUtils.md5Hex(str2+str2_sha));
}catch (Exception e){
System.out.println(e);
}
}
2.MD5还安全么?
我个人认为是安全的。主要是有一下原因
i.加密信息的不确定性,比如,当你要加密1+99时,MD5也只会加密100(1+99)的值,你可以通过解密推出原文是100,但100却很难推测出是通过1+99得来的。
ii.找到了碰撞也没用,你只是发现两个文件可以有相同的MD5,但你无法反推原文是什么,且商业应用中密码都是层层加密,破解不了的。
iii.可以使用最后解决MD5碰撞的方法,MD5 值碰撞的几率已经很小,再结合 SHA-1 的话,基本上就不会发生碰撞的问题出现了
结语
1.参考链接 https://blog.csdn.net/qq_40006446/article/details/80930113
2.各位给个star吧,就当下载那两个文件的csdn积分了
3.欢迎关注,欢迎留言