当前位置: 首页 > news >正文

SpringBoot项目,密码加密之“BCrypt加密”

前言

这种方法,是当前推荐的密码加密方式。(现在不推荐使用MD5加密了)。

如何在springboot项目中,使用bcrypt加密?请分步骤详细介绍一下

一.在Spring Boot项目中使用BCrypt加密的详细步骤

BCrypt是当前推荐用于密码存储的哈希算法,Spring Security提供了开箱即用的支持。以下是完整实现步骤:

一、添加Spring Security依赖

pom.xml中添加依赖:

xml

换行复制代码

1<dependency>
2    <groupId>org.springframework.boot</groupId>
3    <artifactId>spring-boot-starter-security</artifactId>
4</dependency>

或Gradle项目:

groovy

换行复制代码

1implementation 'org.springframework.boot:spring-boot-starter-security'

二、配置BCryptPasswordEncoder

方式1:通过配置类(推荐)

java

换行复制代码

1import org.springframework.context.annotation.Bean;
2import org.springframework.context.annotation.Configuration;
3import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
4import org.springframework.security.crypto.password.PasswordEncoder;
5
6@Configuration
7public class SecurityConfig {
8    
9    @Bean
10    public PasswordEncoder passwordEncoder() {
11        // 默认强度为10,可以传入4-31之间的值
12        return new BCryptPasswordEncoder();
13    }
14}

方式2:直接注入使用

java

换行复制代码

1@Autowired
2private PasswordEncoder passwordEncoder;

三、密码加密与验证实践

1. 密码加密(用户注册/修改密码时)

java

换行复制代码

1public class UserService {
2    
3    @Autowired
4    private PasswordEncoder passwordEncoder;
5    
6    public void registerUser(String username, String rawPassword) {
7        // 加密密码
8        String encodedPassword = passwordEncoder.encode(rawPassword);
9        
10        // 保存到数据库(应保存encodedPassword而非原始密码)
11        User user = new User();
12        user.setUsername(username);
13        user.setPassword(encodedPassword);
14        userRepository.save(user);
15    }
16}

2. 密码验证(用户登录时)

java

换行复制代码

1public class AuthService {
2    
3    @Autowired
4    private PasswordEncoder passwordEncoder;
5    
6    @Autowired
7    private UserRepository userRepository;
8    
9    public boolean authenticate(String username, String rawPassword) {
10        User user = userRepository.findByUsername(username);
11        if (user == null) {
12            return false;
13        }
14        
15        // 比较原始密码与加密后的密码是否匹配
16        return passwordEncoder.matches(rawPassword, user.getPassword());
17    }
18}

四、完整用户注册/登录示例

1. 用户实体类

java

换行复制代码

1@Entity
2public class User {
3    @Id
4    @GeneratedValue(strategy = GenerationType.IDENTITY)
5    private Long id;
6    
7    @Column(unique = true)
8    private String username;
9    
10    private String password;
11    
12    // getters and setters
13}

2. 控制器实现

java

换行复制代码

1@RestController
2@RequestMapping("/api/auth")
3public class AuthController {
4    
5    @Autowired
6    private UserService userService;
7    
8    @Autowired
9    private AuthService authService;
10    
11    @PostMapping("/register")
12    public ResponseEntity<?> register(@RequestBody RegisterRequest request) {
13        if (userService.usernameExists(request.getUsername())) {
14            return ResponseEntity.badRequest().body("用户名已存在");
15        }
16        
17        userService.registerUser(request.getUsername(), request.getPassword());
18        return ResponseEntity.ok("注册成功");
19    }
20    
21    @PostMapping("/login")
22    public ResponseEntity<?> login(@RequestBody LoginRequest request) {
23        boolean authenticated = authService.authenticate(
24            request.getUsername(), 
25            request.getPassword()
26        );
27        
28        if (authenticated) {
29            return ResponseEntity.ok("登录成功");
30        } else {
31            return ResponseEntity.status(401).body("用户名或密码错误");
32        }
33    }
34}

五、BCrypt工作原理说明

  1. 自动加盐:BCrypt会自动生成并管理盐值,不需要手动处理
  2. 哈希结构:生成的哈希值格式类似: $2a$10$N9qo8uLOickgx2ZMRZoMy.Mrq4L8mWUf7kUGz6qV0Gv3D6dPQ7fW2 ├─┬─┘├─┬─┘└───────────────────────┬───────────────────────┘ │ │ │ └─ 实际哈希值 │ │ └─ 加密强度(工作因子) │ └─ 算法版本 └─ 标识符
  3. 自适应安全性:通过工作因子(默认10)可以调整计算复杂度

六、高级配置选项

1. 自定义加密强度

java

换行复制代码

1@Bean
2public PasswordEncoder passwordEncoder() {
3    // 强度范围4-31,默认10,每+1计算时间翻倍
4    return new BCryptPasswordEncoder(12);
5}

2. 密码加密策略升级

java

换行复制代码

1@Bean
2public PasswordEncoder passwordEncoder() {
3    // 优先使用BCrypt,兼容旧系统的其他加密方式
4    String encodingId = "bcrypt";
5    Map<String, PasswordEncoder> encoders = new HashMap<>();
6    encoders.put(encodingId, new BCryptPasswordEncoder());
7    encoders.put("sha256", new StandardPasswordEncoder());
8    
9    return new DelegatingPasswordEncoder(encodingId, encoders);
10}

七、测试验证

java

换行复制代码

1@SpringBootTest
2public class BcryptTest {
3    
4    @Autowired
5    private PasswordEncoder passwordEncoder;
6    
7    @Test
8    public void testEncodeAndMatch() {
9        String rawPassword = "mySecretPassword";
10        String encodedPassword = passwordEncoder.encode(rawPassword);
11        
12        System.out.println("加密后的密码: " + encodedPassword);
13        
14        assertTrue(passwordEncoder.matches(rawPassword, encodedPassword));
15        assertFalse(passwordEncoder.matches("wrongPassword", encodedPassword));
16    }
17}

八、安全最佳实践

  1. 永远不要

    • 存储明文密码
    • 使用MD5/SHA-1等过时算法
    • 自己实现加密算法
  2. 应该

    • 使用BCrypt/Argon2/SCrypt等专用密码哈希算法
    • 保持Spring Security的更新
    • 对敏感接口实施速率限制
  3. 额外保护

    java

    换行复制代码

    1// 在WebSecurityConfigurerAdapter中配置
    2@Override
    3protected void configure(HttpSecurity http) throws Exception {
    4    http
    5        .csrf().disable()
    6        .authorizeRequests()
    7        .antMatchers("/api/auth/register").permitAll()
    8        .anyRequest().authenticated()
    9        .and()
    10        .sessionManagement()
    11        .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    12}

通过以上步骤,您已经在Spring Boot项目中正确实现了BCrypt密码加密机制,这比MD5安全得多,且不需要手动处理盐值等复杂问题。

http://www.xdnf.cn/news/98821.html

相关文章:

  • 使用 Streamlit 打造一个简单的照片墙应用
  • 前端渲染pdf文件解决方案-pdf.js
  • 为什么圆形在GeoJSON中被表示为多边形(Polygon)而不是圆形类型
  • 【OSCP-vulnhub】Raven-2
  • pod内部共享命名空间与k8s命名空间是一个东西吗?
  • arm64适配系列文章-第一章-arm64环境上kubesphere和k8s的部署
  • mybatis xml中特殊字符处理
  • 【k8s】Taint污点)、Toleration(容忍)
  • HCIA-Access V2.5_18_网络管理基础_1_网络管理系统架构
  • 去年15天背完高项重点,成功上岸
  • H5S 寒武纪GPU转码
  • 约束constraint
  • PHP 反序列化原生类 TIPS字符串逃逸CVE 绕过漏洞属性类型特征
  • 车载功能测试-车载域控/BCM控制器测试用例开发流程【用例导出方法+优先级划分原则】
  • Linux内核源码结构
  • 数智化浪潮下,智能外呼系统如何重塑沟通格局
  • WinForm实现管理员权限运行的方式
  • 外贸获客新革命:基于AI的搜索引擎排名攻防战——48小时抢占谷歌TOP3的技术逻辑与实战路径
  • 【论文阅读】Visual Instruction Tuning
  • 数字化应用低代码开发平台的崛起
  • AI大模型学习十一:‌尝鲜ubuntu 25.04 桌面版私有化sealos cloud + devbox+minio,实战运行成功
  • 开源作业调度框架Quartz框架详细使用说明
  • XCZU19EG-2FFVC1760I Xilinx赛灵思FPGA Zynq UltraScale+MPSoC
  • 【AI 加持下的 Python 编程实战 2_09】DIY 拓展:从扫雷小游戏开发再探问题分解与 AI 代码调试能力(上)
  • 建站踩得坑,nginx+mysql+php+wordpress
  • Linux笔记---进程间通信:匿名管道
  • 2.2 主流大模型架构:GPT、DeepSeek、GLM、Claude、QwQ、Qwen2.5-Max等模型的比较与应用场景
  • C++初阶-类和对象(下)
  • Unity常用内置变换矩阵
  • C++20 module下的LVGL模拟器