数据加盐处理(密码加盐)

发布于:2025-09-06 ⋅ 阅读:(16) ⋅ 点赞:(0)

数据加盐处理(密码加盐)

简介:

加盐(Salting)是一种密码安全技术,主要用于增强密码存储的安全性,防止常见的攻击手段(如彩虹表攻击)。

为什么需要加盐?

明文存储密码:如果直接存储用户密码的明文,数据库泄露会导致所有账号被盗。

单纯哈希(Hash)的缺陷: 即使对密码做哈希(如 SHA-256),攻击者仍可通过彩虹表(预先计算的哈希字典)反向破解。

加盐的特点

  • 唯一性:即使两个用户密码相同,加盐后的哈希值也不同。
  • 防彩虹表攻击:攻击者无法批量破解所有密码。

加盐的原理

  1. 生成随机盐值:每个生成随机盐值**:每个用户注册时,系统生成一个唯一的随机字符串(盐)。
  2. 拼接密码和盐:将盐与用户密码组合(如 密码 + 盐 或 盐 + 密码)。
  3. 哈希计算:对组合后的字符串进行哈希(如 SHA-256、BCrypt)。
  4. 存储盐和哈希值:将盐和哈希后的密码一起存入数据库。

实战

环境:vue + spring boot

场景:用户注册、登录

注意:这里作者用到了aes实现对称加密来传输数据,详情请移步:

AES介绍以及应用(crypto.js 实现数据加密)-CSDN博客

数据:

首先创造表user

Spring boot

Pom依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<!-- Jackson (Spring Boot 默认集成) -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version>
</dependency>

创建工具类:

// 使用BCrypt自动处理盐值
public static String hashPassword(String password) {
    // 创建BCrypt密码编码器
    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    // 生成密码哈希
    return encoder.encode(password);
}

// 验证密码
public static boolean checkPassword(String inputPassword, String storedHash) {
    // 创建BCrypt密码编码器
    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    // 验证密码
    return encoder.matches(inputPassword, storedHash);
}

控制层:

//创建账号   //加盐
@PostMapping("/user/register")
public Result register(@RequestBody EncryptedRequest request) throws Exception{

    //aes解密

    String decryptedData = AESUtil.decrypt(request.getData());

    //将解密后的JSON字符串转换为User对象
    User user = JSON.parseObject(decryptedData, User.class);

    //判断是否为空
    if (user.getUserName() == null || user.getPassword() == null) {
        return Result.error("501","用户名或密码不能为空");
    }
    //判断用户名是否已存在
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("user_name", user.getUserName());
    if (userService.getOne(queryWrapper) != null) {
        return Result.error("502","用户名已存在");
    }
    //加盐
    user.setPassword(ADDSalt.hashPassword(user.getPassword()));
    userService.save(user);
    return Result.success();
}



//登录
@PostMapping("/user/login")
public Result login(@RequestBody EncryptedRequest request) throws Exception{

    //aes解密

    String decryptedData = AESUtil.decrypt(request.getData());

    //将解密后的JSON字符串转换为User对象
    User user = JSON.parseObject(decryptedData, User.class);
    if (user.getUserName() == null || user.getPassword() == null) {
        return Result.error("501","用户名或密码不能为空");
    }
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("user_name", user.getUserName());
    User one = userService.getOne(queryWrapper);
    if (one == null) {
        return Result.error("503","用户不存在");
    }
    //验证密码
    if (!ADDSalt.checkPassword(user.getPassword(), one.getPassword())) {
        return Result.error("504","密码错误");
    }
    return Result.success();
}

Vue:

      //加密数据

      const encrypted = Encrypt(JSON.stringify(values))

      // 实现注册逻辑

      const response = await request.post('/user/register', { data: encrypted })

      console.log('注册:', values)



      //加密数据

      const encrypted = Encrypt(JSON.stringify(values))

      // 实现登录逻辑

      const response = await request.post('/user/login', { data: encrypted })

实体类

@Data
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String userName;
    private String password; // 存储加盐后的哈希值
    //不需要该字段 因为使用BCrypt自动处理盐值,将盐值和密码都加密放在了password中
//    private String salt;     // 存储随机盐值

结果为以下:


网站公告

今日签到

点亮在社区的每一天
去签到