Springboot学习-MD5盐值密码加密 DigestUtils 和 BCryptPasswordEncoder

Springboot学习-MD5盐值密码加密 DigestUtils和BCryptPasswordEncoder

使用场景:当需要从后端向数据库中存储密码类型的信息时,可以采取可逆加密或不可逆加密.

MD5盐值加密是一种不可逆加密法.

  • MD5
    • Message Digest algorithm 5 ,信息摘要算法
      • 压缩性:任意长度的数据,算出的MD5值长度都是固定的
      • 容易计算:从源数据计算出MD5值很容易
      • 抗修改性:对原数据进行任何改动(哪怕一个字节),所得到的MD5值都有很大的区别
      • 强抗碰撞:向找到两个不同的数据,使它们具有相同的MD5值,是非常困难的
      • 不可逆(除非暴力破解)
  • 加盐(防止MD5被暴力破解)
    • 通过生成随机数与MD5生成字符串进行组合
    • 数据库同时存储MD5值和salt盐值.验证正确性时使用salt进行MD5即可

1. 使用DigestUtils生成MD5值测试:

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.Md5Crypt;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Test
	void contextLoads() {
    
    
		//直接生成MD5
		String s = DigestUtils.md5Hex("12345");
		System.out.println(s);
		String s1 = DigestUtils.md5Hex("12 345");
		System.out.println(s1);
		//使用指定盐值生成MD5
		String salt1 = Md5Crypt.md5Crypt("12345".getBytes(), "$1$asd");
		System.out.println(salt1);
		String salt2 = Md5Crypt.md5Crypt("12345".getBytes(), "$1$asdf");
		System.out.println(salt2);
	}

结果:

827ccb0eea8a706c4c34a16891f84e7b
a8f52e6253698e3fe01df7a79d87c246
$1$asd$dvT8MA7GlGKPOEV7ZkVqT/
$1$asdf$mQUAWMzHGsG/DCuBKc9vY.

密码加密使用方法:

  1. 使用DigestUtils进行MD5盐值加密时,需要在数据库中同时维护一个salt字段;
  2. 当进行密码认证时,将数据库中的salt字段与用户提交的密码再次进行MD5盐值加密得到结果A;
  3. 比较结果A是否与数据库中存储的password字段相同.

2. 使用spring提供的工具 BCryptPasswordEncoder

​ spring提供了BCryptPasswordEncoder工具底层封装了MD5盐值加密,并且无需在数据库中维持salt字段.

密码加密使用方法:

  1. 创建一个BCryptPasswordEncoder对象;
  2. 使用BCryptPasswordEncoder的encode方法,传入原密码rawPassword,可以得到MD5盐值加密后的编码code,将code维持在数据库的password字段;
    1. 即使原密码相同,每次加密可以产生不同的结果(防止暴力破解)
  3. 使用BCryptPasswordEncoder的matches方法,传入原密码和数据库中保留的password,得到匹配结果.
    1. 无需在数据库中存储salt盐值字段
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.Md5Crypt;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Test
void contextLoads1() {
    
    
   BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
   //使用encode方法对原密码进行加密,每次加密可以产生不同的结果
   String encode = passwordEncoder.encode("123456");
   System.out.println(encode);
   String encode1 = passwordEncoder.encode("123456");
   System.out.println(encode1);
   //使用用户提交的原密码和数据库中的encode对比
   boolean matches = passwordEncoder.matches("123456", encode);
   System.out.println(matches);
   boolean matches1 = passwordEncoder.matches("123456", encode1);
   System.out.println(matches1);

}

结果:

$2a$10$gzmn2TS/w6TKZK5KhBn1F.TDW9UZlGrtonMOuqqgHHc1uCn0gQ0Zu
$2a$10$8Gmb.HfAyosX4PaZporAfOxgIN7x/2ConlNSjyCO1fFS/.4AlzlfG
true
true

猜你喜欢

转载自blog.csdn.net/weixin_44634197/article/details/108404580