密码加密和校验
1. 修改配置类 SecurityConfig,添加两个bean的配置
@Bean PasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); } @Bean public UserDetailsService users() { UserDetails user = User.builder() .username("user") .password("123456") .roles("USER") .build(); UserDetails admin = User.builder() .username("admin") .password("112233") .roles("USER", "ADMIN") .build(); return new InMemoryUserDetailsManager(user, admin); }
- passwordEncoder()方法来说明用户认证密码的校验方式,目前的设置为使用明文进行密码校验
- user方法:Spring Security 提供了一个 UserDetails 的实现类 User,用于用户信息的实例表示。另外,User 提供 Builder 模式的对象构建方式。
- 测试
可以输入在内存构建的用户进行登录,比如:user/123456 admin/112233
- BCrypt密码加密
1 、密码加密介绍
加密类型目前主流的有三种:对称加密、非对称加密和摘要加密
对称加密: 文件加密和解密使用相同的密钥,即加密密钥也可以用作解密密钥
优点:加密速度快,效率高
缺点:相对不太安全(不要保存敏感信息)
非对称加密:两个密钥:公开密钥(publickey)和私有密钥,公有密钥加密,私有密钥解密
优点:与对称加密相比,安全性更高
缺点:加密和解密速度慢,建议少量数据加密
摘要加密:对数据进行哈希运算来生成一个固定长度的摘要(也称为哈希值或消息摘要)
特点:不可逆,唯一性
场景:密码加密、数字签名
常见的加密算法:MD5、BCrypt
2、 Md5加密 VS BCrypt加密
我们现在随便找个类,写个main方法测试一下
package com.zzyl.vo; import org.springframework.security.crypto.bcrypt.BCrypt; import org.springframework.util.DigestUtils; public class PswdTest { public static void main(String[] args) { //md5加密 String md5Pswd1 = DigestUtils.md5DigestAsHex("123456".getBytes()); String md5Pswd2 = DigestUtils.md5DigestAsHex("123456".getBytes()); System.out.println(md5Pswd1); System.out.println(md5Pswd2); System.out.println(md5Pswd1.equals(md5Pswd2)); System.out.println("-------------------------------------"); String password1 = BCrypt.hashpw("123456", BCrypt.gensalt()); String password2 = BCrypt.hashpw("123456", BCrypt.gensalt()); System.out.println(password1); System.out.println(password2); System.out.println(password1.equals(password2)); } }
输出的结果如下:
e10adc3949ba59abbe56e057f20f883e e10adc3949ba59abbe56e057f20f883e true ------------------------------------- $2a$10$rkB/70Cz5UvsE7F5zsBh8O2EYDoGus3/AnVrEgP5cTpsGLxM8iyG6 $2a$10$QIefMa.FmFIb2k2S9/jO7e1S3b0aeXCMtGS/ArKUyt6q28deYQrfy false
- md5对于同一个字符串加密多次都是相同的
- BCrypt对于同一个字符串加密多次是不同的,主要是因为添加了随机盐(随机字符串),更加安全
其中BCrypt提供了一个方法,用于验证密码是否正确
boolean checkpw = BCrypt.checkpw("123456", "$2a$10$rkB/70Cz5UvsE7F5zsBh8O2EYDoGus3/AnVrEgP5cTpsGLxM8iyG6");
- 返回值为true,表示密码匹配成功
- 返回值为false,表示密码匹配失败
3 、改造权限密码加密
接下来,我们看代码如何实现
- 修改配置类SecurityConfig 的passwordEncoder实现类为BCryptPasswordEncoder
@Bean PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
PasswordEncoder的实现类BCryptPasswordEncoder,用于BCrypt密码的解析。
- 修改配置类SecurityConfig 的users方法中的密码,为加密后的密码
@Bean public UserDetailsService users() { UserDetails user = User.builder() .username("user") .password("$2a$10$2VCyByZ5oeiXCEN73wvBB.xpmJgPBbZVS/Aallmdyij2G7hmAKQTG") .roles("USER") .build(); UserDetails admin = User.builder() .username("admin") .password("$2a$10$cRH8iMMh6XO0T.ssZ/8qVOo8ThWs/qfntIH3a7yfpbPd05h9ZGx8y") .roles("USER", "ADMIN") .build(); return new InMemoryUserDetailsManager(user, admin); }
大家可以使用BCrypt对想要的字符串进行加密后填充到上面的password中
- 再次测试
输入user,密码为加密前的密码,比如123456,如果登录成功,则表示认证成功(密码校验也成功)
结论
到现在为止呢,我们就清楚了Spring Security内部使用了BCrypt来进行加密和校验,这种加密方式相对于MD5来说更加的安全。