概念

MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。

  1. MD5算法不可逆只有加密过程没有解密过程
  2. 加密内容相同无论加密多少次生成结果始终一致

因为这两个特性所以,我们使用MD5加密时,数据库保存的密码应该是加密过的,当用户登录时,将输入的密码进行MD5加密,加密后进行比较是否相等。相等则密码正确!

同时因为加密内容相同无论加密多少次生成结果始终一致,所以一些简单的密码是能被破解的,例如123,它的密文就是202cb962ac59075b964b07152d234b70。原理就是这些破解网站对通过穷举字符组合的方式,创建了明文密文对应查询数据库。

https://www.cmd5.com/

image-20211121170103126

为了防止这种情况,可以对它进行多次散列,或者salt盐加密。

盐加密

盐(Salt),在密码学中,是指在散列之前将散列内容(例如:密码)的任意固定位置插入特定的字符串。这个在散列中加入字符串的方式称为 “加盐”。其作用是让加盐后的散列结果和没有加盐的结果不相同,在不同的应用情景中,这个处理可以增加额外的安全性。

在大部分情况,盐是不需要保密的。盐可以是随机产生的字符串,其插入的位置可以也是随意而定。如果这个散列结果在将来需要进行验证(例如:验证用户输入的密码),则需要将已使用的盐记录下来。

用户注册时,

  1. 用户输入【账号】和【密码】(以及其他用户信息);
  2. 系统为用户生成【Salt值】;
  3. 系统将【Salt值】和【用户密码】连接到一起;
  4. 对连接后的值进行散列,得到【Hash值】;
  5. 将【Hash值1】和【Salt值】分别放到数据库中。
    用户登录时,

用户登录时,

  1. 用户输入【账号】和【密码】;
  2. 系统通过用户名找到与之对应的【Hash值】和【Salt值】;
  3. 系统将【Salt值】和【用户输入的密码】连接到一起;
  4. 对连接后的值进行散列,得到【Hash值2】(注意是即时运算出来的值);
  5. 比较【Hash值1】和【Hash值2】是否相等,相等则表示密码正确,否则表示密码错误。

有时候,为了减轻开发压力,程序员会统一使用一个salt值(储存在某个地方),而不是每个用户都生成私有的salt值。

Shiro中的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class TestShiroMD5 {

public static void main(String[] args) {

//创建一个md5算法 error
//Md5Hash md5Hash = new Md5Hash();
//md5Hash.setBytes("123".getBytes());
//String s = md5Hash.toHex();
//System.out.println(s);

Md5Hash md5Hash = new Md5Hash("123",null,2);
System.out.println(md5Hash.toHex());

//使用MD5 + salt处理
Md5Hash md5Hash1 = new Md5Hash("123", "X0*7ps");
System.out.println(md5Hash1.toHex());

//使用MD5 + salt处理 + hash散列
Md5Hash md5Hash2 = new Md5Hash("123", "X0*7ps", 1024);
System.out.println(md5Hash2.toHex());

}
}

使用Md5Hash构造

  • source要加密的值
  • salt盐值
  • hashIterations散列次数

使用toHex()获取加密后的值

image-20211121171311537

推荐文章

https://segmentfault.com/a/1190000021691476