应用场景:密码加密
引言:MD5将任意长度的"字节串"变换成一个128bit的大整数,并且它是一个不可逆的字符串变换算法,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。
原理:其最经典的应用场景就是用户密码的加密,在很多操作系统中,用户的密码是以MD5值(或类似的其它算法)的方式保存的,用户Login的时候,系统是把用户输入的密码计算成MD5值,然后再去和数据库中保存的MD5值进行比较,而系统并不"知道"用户的密码是什么,大大提高了密码的安全性。
//字符串密码md5加密
String md5Pass = DigestUtils.md5DigestAsHex(password.getBytes());
数据库里的内容:
使用方法:
pom.xl
<dependency> 2 <groupId>commons-codec</groupId> 3 <artifactId>commons-codec</artifactId> 4 <version>1.6</version> 5 </dependency>
使用工具DigestUtils:
1 String s = DigestUtils.md5Hex(password.getBytes());
![密码加密 密码加密](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWcyMDIzLmNuYmxvZ3MuY29tL2Jsb2cvMjkxMzk2NC8yMDIzMDIvMjkxMzk2NC0yMDIzMDIxOTE3MDc0NDUzMy04ODE1NDkxNDYucG5n.png?w=700&webp=1)
代码实现:
密码一样,加密结果一样:(第一个疑问:就是这个为啥输入一样的字符串,加密结果一样,然后不可逆,可能就算窃取数据库后也得不到密码吧(我认为));
第二种方法:
使用spring提供的工具 BCryptPasswordEncoder
spring提供了BCryptPasswordEncoder工具底层封装了MD5盐值加密,并且无需在数据库中维持salt字段.
密码加密使用方法:
创建一个BCryptPasswordEncoder对象;
使用BCryptPasswordEncoder的encode方法,传入原密码rawPassword,可以得到MD5盐值加密后的编码code,将code维持在数据库的password字段;
即使原密码相同,每次加密可以产生不同的结果(防止暴力破解)
使用BCryptPasswordEncoder的matches方法,传入原密码和数据库中保留的password,得到匹配结果.
无需在数据库中存储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
这个是每次加密不一。