首页 > 其他分享 >[spring security]使用BCryptPasswordEncoder对明文密码加密后匹配失败

[spring security]使用BCryptPasswordEncoder对明文密码加密后匹配失败

时间:2023-01-17 14:22:58浏览次数:60  
标签:rawPassword 加密 String BCryptPasswordEncoder spring passwordEncoder 密码 security

参考: https://www.cnblogs.com/flydean/p/15292400.html

问题

项目中使用Spring Security+JWT做认证授权
做修改密码逻辑时原逻辑如下

select oldPwd from user where id = 1;
if(oldPwd.equals(encoder.encode(newPwd))){ // always false
	// 旧密码匹配正确 可以执行修改密码逻辑
}

分析

两次加密同一串密码后得到的密文是否相同?

BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

String encode1 = passwordEncoder.encode("1234");
String encode2 = passwordEncoder.encode("1234");

System.out.println(encode1);
System.out.println(encode2);

输出:
$2a$10$JDJEy1MDjrSE4Dt3RZw/1OZtMiR0kX.Ya.5P6r5YfvdgyoCPB9vN2
$2a$10$mnmHsD/IjxJBpPm1ge3Fe.GCzz/8gj6j9te2uERJS4IV/ocwKl5Fe

可以看到, 得到的密文并不相同.
根本原因是使用BCryptPasswordEncoder加密时会使用随机盐对密码加密.

	@Override
	public String encode(CharSequence rawPassword) {
		if (rawPassword == null) {
			throw new IllegalArgumentException("rawPassword cannot be null");
		}
		String salt = getSalt();
		return BCrypt.hashpw(rawPassword.toString(), salt);
	}
	
	private String getSalt() {
		if (this.random != null) {
			return BCrypt.gensalt(this.version.getVersion(), this.strength, this.random);
		}
		return BCrypt.gensalt(this.version.getVersion(), this.strength);
	}

解决

应该使用BCryptPasswordEncoder#matches(CharSequence rawPassword, String encodedPassword)方法对新旧密码进行匹配

System.out.println(passwordEncoder.matches("1234", encode1));
System.out.println(passwordEncoder.matches("1234", encode2));

输出:
true
true

标签:rawPassword,加密,String,BCryptPasswordEncoder,spring,passwordEncoder,密码,security
From: https://www.cnblogs.com/javanoob0660/p/17057672.html

相关文章

  • Spring Boot 配置文件
    SpringBoot配置文件SpringBoot官方提供了两种常用的配置文件格式,分别是properties、yml格式。相比于properties来说,yml更加年轻,层级也是更加分明。properties和yml......
  • Spring Boot 日志文件
    SpringBoot日志文件日志文件是用于记录系统操作事件的记录文件或文件集合,可分为事件日志和消息日志。具有处理历史数据、诊断问题的追踪以及理解系统的活动等重要作用。......
  • [tomcat]context-securityManager
    示意图简述1. tomcat为平台,如果应用A调用了平台的例如退出方法,将会导致tomcat停机和其他应用都停止服务2. securityManager通过-Djava.security.manager开启-......
  • SpringCloud学习(1)
    今天学习谷粒商城的openfeign远程调用的时候,启动项目后报错nestedexceptionisjava.lang.IllegalStateException:NoFeignClientforloadBalancingdefined.Didyou......
  • 学习笔记——Spring底层IOC实现;Spring依赖注入数值问题;Spring依赖注入方式
    2023-01-14一、Spring底层IOC实现1、IOC:将对象的控制器反转给Spring2、BeanFactory与ApplicationContext(1)BeanFactory:IOC容器的基本实现,是Spring内部的使用接口,是面向......
  • spring 管理的线程池实现优雅关闭
      创建线程池时, setWaitForTasksToCompleteOnShutdown  setAwaitTerminationSeconds//将ThreadPoolTaskExecutor实例交给Spring管理@BeanpublicThreadPool......
  • Spring-正确使用AOP
    正确使用AOP,我们需要一个避坑指南:访问被注入的Bean时,总是调用方法而非直接访问字段;编写Bean时,如果可能会被代理,就不要编写publicfinal方法。这样才能保证有没有AOP,代......
  • Spring 依赖注入
    依赖注入(DI)是一种设计模式,可以从编程代码中删除依赖,以便可以轻松管理和测试应用程序。依赖注入使我们的编程代码松散耦合。为了更好地理解DI,让我们首先了解依赖关系查......
  • Spring IoC容器
    IoC容器负责实例化,配置和组装对象。IoC容器从XML文件获取信息并相应地工作。IoC容器执行的主要任务是:实例化应用程序类配置对象组装对象之间的依赖关系 有两种类......
  • SpringBoot自定义starter
    SpringBoot自定义starter目录SpringBoot自定义starter1自定义starter1.1新建project和Module1.2对于starter-provider1.3install1.4对于starter-user1.5测试2执行......