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

真实情景之:处理用户密码时的“加盐”措施

目录

  • 引言
  • 加盐措施介绍
    • 什么是加盐?
    • 如何加盐?
  • 完整示例:
      • 1. 项目结构
      • 2. 实体类 (User.java)
      • 3. Mapper接口 (UserMapper.java)
      • 4. Service层 (UserService.java 和 AuthService.java)
      • 5. Controller层 (UserController.java)
      • 6. MyBatis配置文件 (UserMapper.xml)
      • 7. 应用程序入口 (DemoApplication.java)
      • 8. 数据库表结构
  • 优点:
      • 1. 防止彩虹表攻击
      • 2. 增加密码复杂性
      • 3. 防止预计算攻击
      • 4. 提高安全性
      • 5. 防止批量破解
      • 6. 合规性和标准
      • 7. 增强用户体验
      • 8. 可扩展性
      • 9. 透明性
      • 10. 灵活性

引言

在实际项目中,进行登录注册时采用加盐措施是非常重要的安全实践。加盐可以防止密码被轻易破解,即使数据库泄露,攻击者也难以通过预计算的哈希表(如彩虹表)来快速破解用户的密码。

加盐措施介绍

什么是加盐?

  • :是一串随机生成的数据,它与用户的密码一起被哈希处理。
  • 加盐的目的:使得即使两个用户拥有相同的密码,由于使用的盐不同,最终存储的哈希值也会不同,从而增加安全性。

如何加盐?

  1. 为每个用户生成一个独特的盐。
  2. 将用户的密码与盐结合起来。
  3. 对组合后的数据进行哈希处理。
  4. 存储哈希值和盐。
    在这里插入图片描述

在这里插入图片描述

完整示例:

1. 项目结构

项目结构如下:

src
├── main
│   ├── java
│   │   └── com
│   │       └── example
│   │           └── demo
│   │               ├── controller
│   │               │   └── UserController.java
│   │               ├── service
│   │               │   ├── UserService.java
│   │               │   └── AuthService.java
│   │               ├── mapper
│   │               │   └── UserMapper.java
│   │               ├── entity
│   │               │   └── User.java
│   │               └── DemoApplication.java
│   └── resources
│       └── mybatis
│           └── UserMapper.xml

确保pom.xml引入了相关的依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mindrot</groupId>
        <artifactId>jbcrypt</artifactId>
        <version>0.4</version>
    </dependency>
    <!-- 其他依赖 -->
</dependencies>

2. 实体类 (User.java)

package com.example.demo.entity;

import javax.persistence.Id;
import javax.persistence.Table;

@Table(name = "users")
public class User {
    @Id
    private Long id;
    private String username;
    private String password; // 存储的是哈希后的密码
    private String salt;     // 存储盐

    // Getters and Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) {
        this.salt = salt;
    }
}

3. Mapper接口 (UserMapper.java)

package com.example.demo.mapper;

import com.example.demo.entity.User;
import org.apache.ibatis.annotations.*;

@Mapper
public interface UserMapper {

    @Select("SELECT * FROM users WHERE username = #{username}")
    User findByUsername(@Param("username") String username);

    @Insert("INSERT INTO users (username, password, salt) VALUES (#{username}, #{password}, #{salt})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insertUser(User user);
}

4. Service层 (UserService.java 和 AuthService.java)

package com.example.demo.service;

import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public void registerUser(String username, String password) {
        // 生成盐
        String salt = BCrypt.gensalt();
        
        // 使用盐对密码进行哈希处理
        String hashedPassword = BCrypt.hashpw(password, salt);
        
        // 创建用户对象
        User user = new User();
        user.setUsername(username);
        user.setPassword(hashedPassword);
        user.setSalt(salt);
        
        // 保存用户到数据库
        userMapper.insertUser(user);
    }
}

package com.example.demo.service;

import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class AuthService {

    @Autowired
    private UserMapper userMapper;

    public boolean authenticate(String username, String password) {
        // 从数据库获取用户信息
        User user = userMapper.findByUsername(username);
        if (user == null) {
            return false;
        }

        // 比较用户输入的密码与数据库中存储的哈希值
        return BCrypt.checkpw(password, user.getPassword());
    }
}

5. Controller层 (UserController.java)

package com.example.demo.controller;

import com.example.demo.service.AuthService;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/users")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private AuthService authService;

    @PostMapping("/register")
    public ResponseEntity<String> register(@RequestParam String username, @RequestParam String password) {
        userService.registerUser(username, password);
        return ResponseEntity.ok("User registered successfully");
    }

    @PostMapping("/login")
    public ResponseEntity<String> login(@RequestParam String username, @RequestParam String password) {
        if (authService.authenticate(username, password)) {
            return ResponseEntity.ok("Login successful");
        } else {
            return ResponseEntity.status(401).body("Invalid credentials");
        }
    }
}

6. MyBatis配置文件 (UserMapper.xml)

通常情况下,使用注解时不需要XML配置文件,但如果需要更复杂的SQL查询,可以创建一个UserMapper.xml文件来定义这些查询。

7. 应用程序入口 (DemoApplication.java)

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

8. 数据库表结构

CREATE TABLE `users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `salt` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UK_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

优点:

在用户认证系统中使用加盐措施来处理密码有许多优点,特别是在安全性方面。以下是加盐措施的主要优点:

1. 防止彩虹表攻击

  • 彩虹表是一种预先计算好的哈希值列表,用于快速破解密码。通过为每个用户的密码添加一个随机的盐,即使两个用户选择了相同的密码,生成的哈希值也会不同。这使得攻击者无法直接使用彩虹表来破解密码。

2. 增加密码复杂性

  • 盐是随机生成的,并且对于每个用户都是唯一的。这意味着即使密码本身很简单,加入盐后生成的哈希值也会变得非常复杂。这增加了攻击者通过暴力破解或字典攻击成功破解密码的难度。

3. 防止预计算攻击

  • 预计算攻击是指攻击者事先计算出大量可能的密码哈希值,然后在实际攻击时进行匹配。由于盐的存在,每次都需要重新计算哈希值,使得预计算攻击变得不可行。

4. 提高安全性

  • 即使数据库被泄露,攻击者也无法轻易地获取到用户的原始密码。因为即使他们知道哈希算法和盐,也需要大量的计算资源来尝试破解每个用户的密码。

5. 防止批量破解

  • 如果多个用户使用了相同的密码,但由于盐的不同,他们的哈希值也不同。这使得攻击者无法通过一次破解来获取多个用户的密码,从而大大降低了批量破解的风险。

6. 合规性和标准

  • 许多安全标准和法规(如PCI DSS、GDPR等)要求对敏感数据(如密码)进行适当的保护。使用加盐措施是符合这些标准和法规的一种常见做法。

7. 增强用户体验

  • 用户可能会选择简单的密码,因为他们觉得这样更容易记住。通过加盐措施,即使用户选择了简单的密码,系统的安全性也不会受到太大影响,从而提高了用户体验。

8. 可扩展性

  • 加盐措施可以很容易地集成到现有的认证系统中,而不需要对现有架构进行大规模改动。这使得它成为一种易于实施的安全增强措施。

9. 透明性

  • 对于用户来说,加盐过程是透明的。用户只需要提供他们的用户名和密码,而不需要了解后台是如何处理这些信息的。这简化了用户操作,同时提高了安全性。

10. 灵活性

  • 可以根据需要调整盐的长度和复杂性。例如,可以使用更长的盐来进一步增加安全性,或者使用不同的盐生成算法来适应不同的安全需求。

http://www.kler.cn/a/421941.html

相关文章:

  • JavaScript 键盘控制移动
  • 【C++】C与C++基本区别以及构造函数
  • PostgreSQL认证培训需要什么条件
  • 装饰器—购物打折
  • 如何预防服务器后台爆破攻击
  • 深入傅里叶级数与傅里叶变换:从基础到应用
  • 基于 MVC 的 SpringBoot 高校行政事务管理系统:设计布局与实现效能评估
  • 泷羽sec学习打卡-shell命令5
  • 面向对象(二)——类和对象(上)
  • DevOps工程技术价值流:GitLab源码管理与提交流水线实践
  • 计算机网络-Wireshark探索IPv4
  • C# 元组
  • 外卖开发(三)开发笔记——AOP实现实现公共字段填充、主键回显、抛异常和事务管理
  • Matlab图像处理——基于内容的图像检索GUI
  • 基于云模型的车辆行驶速度估计算法matlab仿真
  • 【C++】数组
  • jmeter 获取唯一全局变量及多线程读写的问题
  • JavaScript实现tab栏切换
  • 从零开始搭建图像去雾神经网络
  • React基础知识三 router路由全指南
  • springboot/ssm高校线上心理咨询室系统Java大学生心理健康咨询平台web源码
  • 用micropython 操作stm32f4单片机的定时器实现蜂鸣器驱动
  • 【数据结构】队列的概念、结构和实现详解
  • 【layui】 自己编写的可输入下拉框
  • HCIA笔记6--路由基础与静态路由:浮动路由、缺省路由、迭代查找
  • Ubuntu WiFi检测