数据库用户密码加密

1.实现PasswordEncoder接口

  • 通过实现PasswordEncoder接口设置自定义的密码加密规则和匹配规则

  • 实现三次带盐的SM3加密

  • 实现逻辑为SM3(SALT+SM3(SALT+SM3(SALT+PASSWORD)))

    com/gaomu/utils/crypto/SM3PasswordEncoder.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

public class SM3PasswordEncoder implements PasswordEncoder {
//密码加密规则
@Override
public String encode(CharSequence rawPassword) {
String pwdDigest = rawPassword.toString();
for (int i = 0; i < 3; i++){
pwdDigest = SM3Util.passwordDigest(pwdDigest);
}
return pwdDigest;
}
//密码匹配规则
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
String pwdDigest = rawPassword.toString();
for (int i = 0; i < 3; i++){
pwdDigest = SM3Util.passwordDigest(pwdDigest);
}
return pwdDigest.equals(encodedPassword);
}
}

2.SM3加密过程

  • passwordDigest实现过程

    com/gaomu/utils/crypto/SM3Util.java

1
2
3
4
5
6
7
8
public static String USER_PASSWORD_SLAT = "password_salt";

public static String passwordDigest(String data){
SM3 sm3 = SmUtil.sm3WithSalt(USER_PASSWORD_SLAT.getBytes(StandardCharsets.UTF_8));
byte[] hash = sm3.digest(data.getBytes());
//返回16进制字符串,256bits
return HexUtil.encodeHexStr(hash);
}

3.注入容器

  • 在SecurityConfig中添加Bean注解

    com/gaomu/config/SecurityConfig.java

1
2
3
4
5
6
7
8
9
@Bean
public SM3PasswordEncoder sm3PasswordEncoder() {
return new SM3PasswordEncoder();
}
//配置授权过滤器的密码规则
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(sm3PasswordEncoder());
}

4.生成数据库摘要

  • 测试main方法

    com/gaomu/utils/crypto/SM3PasswordEncoder.java

1
2
3
4
5
6
7
8
public static void main(String[] args){
//生成数据库密码
String originalPassword = "admin123";
System.out.println("originalPassword: " + originalPassword);
SM3PasswordEncoder sm3PasswordEncoder = new SM3PasswordEncoder();
String pwdDigest = sm3PasswordEncoder.encode(originalPassword);
System.out.println("pwdDigest: " + pwdDigest);
}

image-20231230134455151

image-20231230134615002

5.匹配用户密码

  • 在认证过滤器中匹配,UsernamePasswordAuthenticationToken会调用只定义的密码匹配规则进行匹配

    com/gaomu/server/impl/LoginServiceImpl.java

1
2
3
4
5
6
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());
Authentication authenticate = authenticationManager.authenticate(authenticationToken);
//如果认证没通过,给出对应提示
if(Objects.isNull(authenticate)){
throw new RuntimeException("authenticate 为空,登陆失败!");
}