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

Java Spring Boot 项目中的密码加密与验证开发案例手册

本手册主要针对Java项目中的账号密码加密与验证进行详细的步骤讲解和代码示例。适用于开发登录认证、用户管理等功能的场景。文档包含工具类的创建、数据库配置、服务层和控制器层的集成等常见操作。

1. 常用加密操作

在实现安全的登录功能时,密码加密与验证是不可或缺的一部分。常用的加密流程如下:

1.1 密码加密

在用户注册或修改密码时,应该对密码进行加密。常用的加密方法有:

  • MD5:已不建议使用,因为安全性不足。
  • SHA-256:推荐使用,安全性较好。
  • 加盐:为了增加安全性,加密时应生成并使用一个随机的“盐值”。

加盐加密步骤

  1. 生成随机的盐值。
  2. 将盐值与密码组合,生成哈希。
  3. 将哈希值和盐值存储到数据库中。

1.2 盐值生成

为了确保每个用户的密码加密结果唯一,使用随机盐值非常重要。通过 SecureRandom 类可以生成高质量的随机盐值。

public static String generateSalt() {byte[] salt = new byte[16];new SecureRandom().nextBytes(salt);return Base64.getEncoder().encodeToString(salt);
}

1.3 加密密码的存储与验证

存储时不直接保存用户密码,而是保存加密后的哈希值和对应的盐值。在用户登录时,使用存储的盐值对用户输入的密码进行加密,然后比对哈希值。


2. 系统结构与配置

2.1 项目结构概述

假设项目使用Spring Boot框架(lombok),项目的基本结构如下:

├─src
│  ├─main
│  │  ├─java
│  │  │  └─com
│  │  │      └─company
│  │  │          └─erp
│  │  │              ├─config
│  │  │              ├─constant
│  │  │              ├─dto
│  │  │              ├─entity
│  │  │              ├─mapper
│  │  │              ├─service
│  │  │              ├─util
│  │  │              └─web

2.2 数据库设计

为实现密码加密功能,需要修改数据库表结构,保存哈希后的密码和对应的盐值。
示例数据库表结构如下:

CREATE TABLE emp (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(255) NOT NULL UNIQUE,password_hash VARCHAR(255) NOT NULL,salt VARCHAR(255) NOT NULL
);

3. 代码实现

3.1 工具类 PasswordUtils

加密和验证密码的工具类,包含生成盐值、加密密码和验证密码的方法。

public class PasswordUtils {// 生成随机盐值public static String generateSalt() {byte[] salt = new byte[16];new SecureRandom().nextBytes(salt);return Base64.getEncoder().encodeToString(salt);}// 使用盐值对密码进行哈希处理public static String hashPassword(String password, String salt) throws NoSuchAlgorithmException {MessageDigest md = MessageDigest.getInstance("SHA-256");md.update(Base64.getDecoder().decode(salt));byte[] hashedPassword = md.digest(password.getBytes());return Base64.getEncoder().encodeToString(hashedPassword);}// 验证密码是否匹配public static boolean verifyPassword(String password, String salt, String storedHash) throws NoSuchAlgorithmException {String hash = hashPassword(password, salt);return hash.equals(storedHash);}
}

3.2 实体类 Emp

实体类代表数据库中的用户信息,需要包含加密后的密码和盐值。

@Data
public class Emp {private Integer id;private String username;private String passwordHash; // 存储加密后的密码private String salt; // 存储盐值
}

3.3 数据访问层 EmpMapper

通过 EmpMapper 进行数据库操作。它负责将用户信息插入数据库以及根据用户名查找用户信息。

public interface EmpMapper {@Insert("INSERT INTO emp (username, password_hash, salt) VALUES (#{username}, #{passwordHash}, #{salt})")void insert(Emp emp);@Select("SELECT * FROM emp WHERE username = #{username}")Emp findByUsername(String username);
}

3.4 服务层 EmpServiceEmpServiceImpl

服务层负责处理用户注册和登录的业务逻辑,使用 PasswordUtils 工具类对密码进行加密和验证。

@Service
public class EmpServiceImpl implements EmpService {@Autowiredprivate EmpMapper empMapper;@Overridepublic void registerUser(String username, String password) {String salt = PasswordUtils.generateSalt();try {String hashedPassword = PasswordUtils.hashPassword(password, salt);Emp emp = new Emp();emp.setUsername(username);emp.setPasswordHash(hashedPassword);emp.setSalt(salt);empMapper.insert(emp);} catch (NoSuchAlgorithmException e) {throw new RuntimeException("Error while hashing password", e);}}@Overridepublic boolean authenticateUser(String username, String password) {Emp emp = empMapper.findByUsername(username);if (emp == null) {return false;}try {return PasswordUtils.verifyPassword(password, emp.getSalt(), emp.getPasswordHash());} catch (NoSuchAlgorithmException e) {throw new RuntimeException("Error while verifying password", e);}}
}

3.5 控制器层 LoginController

控制器层负责接收前端的登录和注册请求,并调用服务层进行用户验证。

@RestController
@RequestMapping("/v2")
public class LoginController {@Autowiredprivate EmpService empService;@PostMapping("/login")public String login(@RequestParam String username, @RequestParam String password) {boolean isAuthenticated = empService.authenticateUser(username, password);return isAuthenticated ? "Login successful" : "Invalid credentials";}@PostMapping("/register")public String register(@RequestParam String username, @RequestParam String password) {empService.registerUser(username, password);return "User registered successfully";}
}

4. 最佳实践与安全建议

  1. 加盐加密:确保密码在加密过程中使用随机生成的盐值,使得相同的密码不会产生相同的加密结果。
  2. 算法选择:推荐使用 SHA-256 或更高强度的算法进行加密。
  3. HTTPS:在传输过程中使用 HTTPS 确保密码安全。
  4. 限制登录尝试:为防止暴力破解,限制登录失败的尝试次数。
  5. 使用更高的加密标准:如有需要,可以使用 PBKDF2、bcrypt 或 Argon2 等算法。

5. 完整案例

综合上面的手册内容,这里是一个用户注册和登录的完整流程:

  1. 用户通过前端界面输入用户名和密码。
  2. 后端在用户注册时,使用 PasswordUtils.generateSalt() 生成盐值,并使用 hashPassword() 方法对密码进行加密,然后将加密后的密码和盐值存储到数据库中。
  3. 用户登录时,系统从数据库中查找对应的盐值,使用 verifyPassword() 方法验证用户输入的密码是否匹配。

此流程确保了用户密码的安全性,并能够防止常见的攻击手段,如彩虹表攻击。

相关文章:

Java Spring Boot 项目中的密码加密与验证开发案例手册

本手册主要针对Java项目中的账号密码加密与验证进行详细的步骤讲解和代码示例。适用于开发登录认证、用户管理等功能的场景。文档包含工具类的创建、数据库配置、服务层和控制器层的集成等常见操作。 1. 常用加密操作 在实现安全的登录功能时,密码加密与验证是不可…...

VueSax-解决Vue3报错问题,并支持typescript

以下为坑点 根据官方提示,本人在vue3typescript的项目中添加了vuesax的组件依赖 根据正常的导入依赖思路编写代码,发现typescript一直报 查询vuesax的目录文件发现存在ts文件,于是乎觉得是自己的问题,就查阅gpt与网上资料&#x…...

回归预测 | Matlab基于贝叶斯算法优化XGBoost(BO-XGBoost/Bayes-XGBoost)的数据回归预测+交叉验证

回归预测 | Matlab基于贝叶斯算法优化XGBoost(BO-XGBoost/Bayes-XGBoost)的数据回归预测交叉验证 目录 回归预测 | Matlab基于贝叶斯算法优化XGBoost(BO-XGBoost/Bayes-XGBoost)的数据回归预测交叉验证效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现基于贝叶…...

[数据集][目标检测]电动车入梯进电梯电单车入梯检测数据集VOC+YOLO格式7106张3类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):7106 标注数量(xml文件个数):7106 标注数量(txt文件个数):7106 标注…...

大数常用API

package API;public class BigNum {//如果普通的long和double的精度不足以满足要求,那么可以使用java.math包中的两个类//BigInteger和BigDecimal//前者实现任意精度的整数运算,后者实现任意精度的浮点数运算//BigInteger add(BigInteger other)//BigInt…...

Gartner发布ASCA自动化安全控制评估创新洞察:三年后40%的综合安全厂商都将提供ASCA功能

复杂的安全控制网络、技能差距和快速变化的攻击技术使维持技术安全控制的最佳配置的问题更加复杂。安全和风险管理领导者可以通过自动化安全控制评估来改善他们的安全状况。 主要发现 技术安全控制配置错误是与安全漏洞相关的长期问题。薄弱的安全默认值、配置漂移、为减少误报…...

使用lspci命令获取加速卡型号

文章目录 前言一、lspci -nn 获取具体厂商及设备ID二、使用步骤三、使用3080Ti再查询一下 前言 新到的实验机器和加速卡,安装好之后发现lspci命令没有显示型号,这里记录下使用 Vendor ID和Device ID 通过网页查询获取加速卡具体型号的过程。 一、lspci …...

php代码实例强制下载文件代码例子

php代码实例强制下载文件代码例子 $filename $_GET[file]; //Get the fileid from the URL // Query the file ID $query sprintf("SELECT * FROM tableName WHERE id %s",mysql_real_escape_string($filename)); $sql mysql_query($query); if(mysql_num_rows…...

Opencv中的直方图(3)直方图比较函数compareHist()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 比较两个直方图。 函数 cv::compareHist 使用指定的方法比较两个密集或两个稀疏直方图。 该函数返回 d ( H 1 , H 2 ) d(H_1, H_2) d(H1​,H2​…...

压力测试(内存、磁盘、网络、cpu)

压力测试 1. 内存压力测试工具stressmemtester 2. 磁盘压力测试工具fio (Flexible I/O Tester)dd (Data Duplicator) 3. 网络压力测试工具iperf3speedtest-cli 4. CPU压力测试工具stress-ng 为了满足更详细的需求,以下是针对内存、磁盘和网络压力测试工具的更深入介…...

ArcGIS JSAPI 高级教程 - ArcGIS Maps SDK for JavaScript - 原生代码实现动态扩散效果

ArcGIS JSAPI 高级教程 - ArcGIS Maps SDK for JavaScript - 原生代码实现动态扩散效果 核心代码完整代码:在线示例 ArcGIS Maps SDK for JavaScript 从 4.29 开始增加 RenderNode 类,可以添加数据以及操作 FBO(ManagedFBO)&#…...

Java 设计模式-代理模式

目录 概述 一. 什么是代理模式 1. 举例说明 二. 代理模式作用 1. 保护代理 2. 增强功能 3. 代理交互 4. 远程代理: 三. 代理模式3个角色 四. 静态代理 1. 代码示例: 五. JDK动态代理 1. 代码示例: 六. CGLIB 动态代理 1.代码示…...

CTF靶场之BUUCTF介绍

最后开始关注CTF,我们先了解一下什么CTF:CTF(Capture The Flag)中文一般译作夺旗赛,在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式,最后以夺取FLAG为成功。 从网上找了一个免费的靶场——BUUCTF&#xf…...

学会分析问题,画出分析图,解释问题过程,找出规律 ;整数数组分为左右2个部分,左边位奇数右边偶数

// 整数数组左边是奇数右边是偶数.cpp : Defines the entry point for the console application. //#include "stdafx.h" #include<stdio.h> void swap(int& a,int& b) {int tempa;ab;btemp; } int main(int argc, char* argv[]) {int a[7]{1,2,3,4,5,…...

数学基础 -- 线性代数正交多项式之勒让德多项式展开推导

勒让德多项式展开的详细过程 勒让德多项式是一类在区间 [ − 1 , 1 ] [-1, 1] [−1,1] 上正交的多项式&#xff0c;可以用来逼近函数。我们可以将一个函数表示为勒让德多项式的线性组合。以下是如何推导勒让德多项式展开系数 a n a_n an​ 的详细过程。 1. 勒让德展开的基本…...

Redis实战宝典:从主从模式、哨兵模式、集群模式一步步理解Redis集群

目录标题 Redis 集群的三种模式主从复制主从复制概念主从复制原理主从复制优缺点 哨兵集群哨兵概念哨兵功能下线判断主库选举故障转移哨兵模式优缺点 Cluser 集群Redis 集群的数据分片 Redis 集群的三种模式 在生产环境中&#xff0c;我们使用 Redis 通常采用集群模式&#xf…...

828华为云征文|华为云Flexus X搭建借贷管理系统、二次开发借贷小程序 前端源码uniapp

在华为云828 B2B企业节的盛宴中&#xff0c;Flexus X实例以其卓越的算力性能和灵活的资源配置脱颖而出。对于追求极致性能、渴望在借贷管理、电商交易等场景中脱颖而出的您来说&#xff0c;Flexus X无疑是最佳拍档。搭载创新加速引擎&#xff0c;让您的自建MySQL、Redis、Nginx…...

网站安全需求分析与安全保护工程

网站安全威胁与需求分析 网站安全概念 网站&#xff1a;是基于B/S技术架构的综合信息服务平台&#xff0c;主要提供网页信息及业务后台对外接口服务。 网站安全性&#xff1a; 机密性&#xff1a;网站信息及相关数据不被授权查看或泄露完整性&#xff1a;网站信息及数据不能…...

后谷歌时代

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

【CMake编译报错小复盘】CMAKE_CUDA_ARCHITECTURES,CMake version,GCC version问题

今天在写大模型量化推理框架时遇到了一些编译上的错误&#xff0c;简单复盘一下问题和解决方案&#xff1a; 问题1&#xff1a;CMAKE_CUDA_ARCHITECTURES 报错信息&#xff1a; CMake Error: CMAKE_CUDA_ARCHITECTURES must be non-empty if set cmake和cuda相关的报错通常都…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...