MD5
👀 MD5 是一种常见的加密方式,常用于加密存储密码。全称为:Message-Digest Algoorithm 5,信息摘要算法
它具有以下特性:⛏
- 压缩性:任意长度的数据,算出的 MD5 值都是固定的
- 容易计算:从原数据计算出 MD5 值很容易
- 抗修改性:改变原数据后,所得到的 MD5 值都有很大的差别
- 强抗碰撞:想找到两个不同的数据,使它们具有相同的 MD5 值是非常困难的。
综上:每个数据都对应一个唯一的 MD5 值
例如:123456 的 MD5 值为:e10adc3949ba59abbe56e057f20f883e
MD5值 e10adc3949ba59abbe56e057f20f883e 对应的原数据为 123456
也就是说,如果知道了 MD5 值,就可以反向推出加密前的数据(应为MD5是唯一的)
详情请看:彩虹表
所以我们就无法单独使用 MD5 来进行数据的加密存储。
MD5 的实现方式有很多种,JDK自带的 MessageDigest 和 Spring 封装好的 DigestUtils
import org.junit.jupiter.api.Test;
import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @Test public void messageDigest(){ try { String password = "heroxin"; MessageDigest md = MessageDigest.getInstance("md5"); md.update(password.getBytes()); String hashedPwd = new BigInteger(1, md.digest()).toString(16); System.out.println(hashedPwd); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } }
|
import org.apache.commons.codec.digest.DigestUtils; import org.junit.jupiter.api.Test; @Test public void digestUtils(){ String s = DigestUtils.md5Hex("heroxin"); System.out.println(s); }
|
MD5加盐
为了提高安全性,可以采取加盐的方式。
就是生成一些随机数与 MD5 值进行组合,这些随机数称为 盐 (salt)
这样获取到的新字符串是服务解密为原数据的。
在存储时,数据库同时存储 MD5 值和 salt 值。验证正确性时使用 salt 进行 MD5即可。
具体的实现可以使用 Spring Security 中的 BCryptPasswordEncoder
BCryptPasswordEncoder方法采用SHA-256 +随机盐+密钥对密码进行加密。SHA系列是Hash算法,不是加密算法,使用加密算法意味着可以解密(这个与编码/解码一样),但是采用Hash处理,其过程是不可逆的。
详情请看:BCryptPasswordEncoder
import org.junit.jupiter.api.Test; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Test public void bCryptPasswordEncoder(){ BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); String encode = bCryptPasswordEncoder.encode("heroxin"); System.out.println(encode); }
|
import org.junit.jupiter.api.Test; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Test public void bCryptPasswordEncoder(){ BCryptPasswordEncoder bc = new BCryptPasswordEncoder(); boolean b = bc.matches("heroxin", "$2a$10$4Xvl1DviJqS.ggItgMKmTO6JjbGbiX3btz/qdneVkPmNZ.zhO6br2"); System.out.println(b); }
|