数据加盐处理(密码加盐)
数据加盐处理(密码加盐)
简介:
加盐(Salting)是一种密码安全技术,主要用于增强密码存储的安全性,防止常见的攻击手段(如彩虹表攻击)。
为什么需要加盐?
明文存储密码:如果直接存储用户密码的明文,数据库泄露会导致所有账号被盗。
单纯哈希(Hash)的缺陷: 即使对密码做哈希(如 SHA-256),攻击者仍可通过彩虹表(预先计算的哈希字典)反向破解。
加盐的特点
- 唯一性:即使两个用户密码相同,加盐后的哈希值也不同。
- 防彩虹表攻击:攻击者无法批量破解所有密码。
加盐的原理
- 生成随机盐值:每个生成随机盐值**:每个用户注册时,系统生成一个唯一的随机字符串(盐)。
- 拼接密码和盐:将盐与用户密码组合(如 密码 + 盐 或 盐 + 密码)。
- 哈希计算:对组合后的字符串进行哈希(如 SHA-256、BCrypt)。
- 存储盐和哈希值:将盐和哈希后的密码一起存入数据库。
实战
环境: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; // 存储随机盐值
结果为以下: