Spring Security 已经废弃了 MessageDigestPasswordEncoder,推荐使用 BCryptPasswordEncoder
private static BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
@GetMapping("performance")
public void performance() {
StopWatch stopWatch = new StopWatch();
String password = "Abcd1234";
stopWatch.start("MD5");
//MD5
DigestUtils.md5Hex(password);
stopWatch.stop();
stopWatch.start("BCrypt(10)");
//代价因子为10的BCrypt
String hash1 = BCrypt.gensalt(10);
BCrypt.hashpw(password, hash1);
System.out.println(hash1);
stopWatch.stop();
stopWatch.start("BCrypt(12)");
//代价因子为12的BCrypt
String hash2 = BCrypt.gensalt(12);
BCrypt.hashpw(password, hash2);
System.out.println(hash2);
stopWatch.stop();
stopWatch.start("BCrypt(14)");
//代价因子为14的BCrypt
String hash3 = BCrypt.gensalt(14);
BCrypt.hashpw(password, hash3);
System.out.println(hash3);
stopWatch.stop();
log.info("{}", stopWatch.prettyPrint());
}
制作 8 位密码长度的 MD5 彩虹表需要 5 个月,那么对于 BCrypt 来说,可能就需要几十年,大部分黑客应该都没有这个耐心。
@GetMapping("better")
public UserData better(@RequestParam(value = "name", defaultValue = "zhuye") String name, @RequestParam(value = "password", d efaultValue = "Abcd1234")
String password) {
UserData userData = new UserData();
userData.setId(1L);
userData.setId(1L);
userData.setName(name);
//保存哈希后的密码
userData.setPassword(passwordEncoder.encode(password));
userRepository.save(userData);
//判断密码是否匹配
log.info("match ? {}", passwordEncoder.matches(password, userData.getPassword()));
return userData;
}
我们的密码保存方式: "password": "$2a$10$wPWdQwfQO2lMxqSIb6iCROXv7lKnQq5XdMO96iCYCj7boK9pk6QPC" //格式为:$$$ 第一个$后的 2a 代表算法版本,第二个$后的 10 是代价因子(默认是 10,代表 2 的 10 次方次哈希),第三个$后的 22 个字符是盐,再后面是摘要。