将用户的隐私信息直接保存在数据库下是十分不安全的,因此我们需要对源数据进行加密后再存储到数据库中,本篇文章我将介绍如何通过加盐加密算法+MD5摘要算法对源数据进行加密入库,以及如何在用户登录时验证加密后的数据。
1. MD5摘要算法
在讲解加盐加密算法之前,先给大家解释下什么是摘要加密和MD5信息摘要算法。
1.1 MD5摘要算法简介
摘要加密是一个不可逆的过程,也就是通过摘要算法加密后的数据无法还原回原来的数据。摘要加密的算法有很多种,MD5只是其中的一种摘要算法。
源数据可以通过MD5信息摘要算法(MD5 Message-Digest Algorithm),从而产生出一个128位(16字节)或 64位(8字节)的散列值(hash value),它有下面几个特点:
- 不同的数据对应一个唯一的加密值
- 源数据稍有变更就会导致加密值大幅变化
- 不管源数据的长度多少,加密值的长度永远不变(128位/64位)
给大家演示一下123456这样的数据会被加密成什么样的数据:
注:下面的网站显示32/16位
的加密数据,指的是16进制
的位数,一个16进制数
相当于4个2进制数
,因此下图所示的32/16位
,也就是对应128/64位
的散列值。
1.2 MD5加密的缺陷
但是单凭MD5进行摘要加密其实并不是很安全的,给大家分享一个MD5在线加解密的网站。
我们惊奇的发现我们先前加密的数据通过这个网站居然可以解密出来:
这时大家是否觉得很奇怪,MD5摘要加密不是不可逆的过程吗,为什么可以通过加密后的数据获取到原来的值呢?如果能解密,我要这玩意有什么用呢,这不成小丑了吗!
不要着急,这时仔细看上面的一小行字:目前只能解密1~8位数字。给大家讲下解密的实现原理:
我们前面提到MD5加密算法的一个特点:不同的数据对应一个唯一的加密值,那我直接遍历数据建立一个彩虹表不就得了?
1~8位的数字只要写8个循环来遍历(0~9)的数字不就可以得到所有数据的加密值了吗?要解密,直接根据建立的彩虹表来取值不就得了吗。
知道这个解密原理相信大家应该都明白了:越简单的密码其实是越好解密的。
而加盐加密算法就是让简单的数据变得复杂,复杂到无法建立彩虹表,大大提升解密的成本,接下来就给大家介绍加盐加密算法的思想以及实际应用。
2. 加盐加密算法
如果只是将一个原食材进行烹饪,那么通过一种食材烹饪出来的所有食物味道都是相同的。为了让味道不同,厨师会往食材里加调料(盐),此时就让同一种食材有了不同的味道。
关于你加的是什么盐(salt),加了多少,这些问题是难以推敲的,所谓加盐加密算法就是起到这样的作用。
因此我们可以给源数据以某种规则拼接一个盐值(加盐),再将其使用MD5进行整体加密,再存入数据库中。
2.1 加盐加密常用类介绍
这里给大家介绍本篇文章将使用到的加盐加密的类。
2.1.1 java.uitl.UUID
使用java.util.UUID
这个类可以获取一个全局唯一的随机值,我们可以用它来当作盐值。
@Test
void contextLoads() {
String salt1 = UUID.randomUUID().toString();
String salt2 = UUID.randomUUID().toString();
String salt3 = UUID.randomUUID().toString();
System.out.println(salt1);
System.out.println(salt2);
System.out.println(salt3);
}
成功获取到几个相对复杂并且随机的盐值:
380ab9d5-3766-4a9d-82bb-c6a7c7251a6c
e581fb89-7de5-41fd-839b-f949d74853c7
05574954-636c-48a9-9295-7fd398ab99c6
对源数据进行拼接:
String originPassword = "123456";
String saltPassword1 = salt1 + originPassword