【SpringBoot】MD5加盐算法的详解

目录

一、什么是加盐算法

二、如何实现加盐算法

2.1 加盐算法代码实现

2.2 注册页面中进行密码加盐

2.3 登录页面进行加盐的解密

2.4 注册和登录


一、什么是加盐算法

加盐算法是一种用于增强密码安全性的技术。这种技术通过在密码存储过程中添加一个随机生成的盐值(salt),来增加密码被破解的难度。举个例子:

在日常生活中,做菜是生活中的基本操作。炒青菜餐桌中必备的一道菜,不同的人炒青菜放盐的程度是不同的,换句话来说不同的人炒同一种菜放盐的多与少是一种随机的操作。因此,在注册账号时,不同用户在注册时难免会使用相同的密码。加盐算法会根据不同的用户生成一串随机的字符串与用户所输入的密码进行结合生成一个最终的结果值,而这个最终值得到的就是加密后的密码。

具体来说,加盐加密的过程如下:

  1. 生成盐值:后端在存储一个密码时,首先会随机生成一个盐值。这个盐值是一个随机字符串,用于增加密码的复杂性。
  2. 结合盐值和密码:将生成的盐值和用户输入的密码进行有规则的结合,通常是将盐值附加在密码的前面或后面,或者通过其他方式进行组合。
  3. 加密处理:将结合后的数据使用加密算法进行加密。常见的加密算法包括MD5、SHA-256等。在Spring Security中,还可以使用更强大的加密方式,如BCrypt。本期讲解使用MD5
  4. 存储加密后的数据和盐值:将加密后的数据和盐值按照一定规则组合起来,并存储在数据库中。通常,盐值会被保存在与加密密码相同的记录中,以便在验证用户密码时使用。

二、如何实现加盐算法

2.1 加盐算法代码实现

首先,我们要了解到:

生成一个随机盐值可使用 UUID UUID 是一个128比特的数值,通常由 32 个 16 进制数字组成,并以连字号分为五段,例如:550e8400-e29b-41d4-a716-446655440000,因此可使用 replace 方法去除 -

生成一个 MD5 散列值,可使用 DigestUtils类 中的 .md5DigestAsHex 方法将生成的随机盐值 salt password 结合,并通过 .getBytes 将结合后的字符串转换成一个字节数组即 .getBytes(StandardCharsets.UTF_8)

此外需要注意的是:

  • MD5(Message-Digest Algorithm 5)是一种广泛使用的散列函数,可以产生一个128位(16字节)的散列值,通常表示为32位的十六进制数。
  • md5DigestAsHex 是 DigestUtils 类中的一个静态方法。这个方法接受一个字节数组作为输入,计算其MD5散列值,并将结果转换为十六进制字符串。
  • StandardCharsets.UTF_8 是一个表示UTF-8字符集的常量,它指定了字符串到字节数组的编码方式。

代码实现:

/*** 加密工具类*/
public class PasswordUtils {public static String encrypt(String password){// 1.盐值String salt = UUID.randomUUID().toString().replace("-","");// 2.将盐值+密码进行 md5 得到最终密码String finalPassword = DigestUtils.md5DigestAsHex((salt+password).getBytes(StandardCharsets.UTF_8));// 3.将盐值和最终密码返回return salt+"$"+finalPassword;}/*** 加盐验证* @param password 待验证的密码* @param dbPassword 数据库中的密码:盐值$最终密码* @return*/public static boolean decrypt(String password,String dbPassword) {if(!StringUtils.hasLength(password) || !StringUtils.hasLength(dbPassword)|| dbPassword.length() != 65) {return false;}// 1.得到盐值String[] dbPasswordArray = dbPassword.split("\\$") ;if (dbPasswordArray.length != 2) {return false;}//盐值String salt = dbPasswordArray[0];//最终正确密码String dbFinalPassword = dbPasswordArray[1];// 2.加密待验证的密码String finalPassword = DigestUtils.md5DigestAsHex((salt+password).getBytes(StandardCharsets.UTF_8));// 3.对比if (finalPassword.equals(dbFinalPassword)) {return true;}return false;}public static void main(String[] args) {// 得到盐值和最终密码一共65位System.out.println(encrypt("111"));}
}

在该类中生成一个 main 方法,测试最后生成的字符串符不符合预期,输出结果:

将上述的字符串,定义为一个字符串,验证是否加密成功。 

    public static void main(String[] args) {
/*        // 得到盐值和最终密码一共65位System.out.println(encrypt("111"));*/String dbPassword = "0f0d62e88c6c41dc83163e2813147111$b7321a14e1e5f3360a0d0d59e2b3cd6e";System.out.println("当密码为123时:"+decrypt("123",dbPassword));System.out.println("当密码为111时:"+decrypt("111",dbPassword));}

 


2.2 注册页面中进行密码加盐

    /*** 注册* @param userinfo* @return*/@RequestMapping("/reg")public ResultAjax reg(Userinfo userinfo) {// 1.校验参数if (userinfo == null || !StringUtils.hasLength(userinfo.getUsername()) ||!StringUtils.hasLength(userinfo.getPassword())) {return ResultAjax.fail(-1,"异常");}// 实现密码加盐userinfo.setPassword(PasswordUtils.encrypt(userinfo.getPassword()));// 2.请求接口 service 进行添加接口int ret = userService.reg(userinfo);// 3.将结果返回给前端return ResultAjax.success(ret);}

2.3 登录页面进行加盐的解密

/*** 登录* @param userinfoVO* @return*/@RequestMapping("/login")public ResultAjax login(UserinfoVO userinfoVO, HttpServletRequest request) {// 1.参数校验if (userinfoVO == null || !StringUtils.hasLength(userinfoVO.getUsername())|| !StringUtils.hasLength(userinfoVO.getPassword())) {// 非法登录return ResultAjax.fail(-1,"非法登录!");}// 2.根据用户名查询对象,判断用户名是否错误Userinfo userinfo = userService.getUserByName(userinfoVO.getUsername());if (userinfo == null && userinfo.getId() == 0) {return ResultAjax.fail(-2,"账号或密码错误!");}// 3.使用对象中的密码和输入的密码进行对比,判断密码是否错误// 加盐解密if (!PasswordUtils.decrypt(userinfoVO.getPassword(),userinfo.getPassword())) {return ResultAjax.fail(-2,"账号或密码错误!");}// 4.成功后将对象存储到 session 中HttpSession session = request.getSession();session.setAttribute(ApplicationVariable.SESSION_USERINFO_KEY,userinfo);// 5.结果返回给用户return ResultAjax.success(1);}

 此时查询数据库中,只有一条数据,下面再注册一个用户,观察是否生成密码。


2.4 注册和登录

注册页面

 输入用户名 lisi 和密码 123 后,提示注册成功。

在数据中查询对应的数据,验证密码 123 被加秘为一大串字符串。

再来到登录页面,输入用户名 lisi 和密码 123,提示登陆成功。 

跳转到个人页面。

注册页面和登录页面的讲解和源码在前两篇博客中已有详细的讲解,感兴趣可以去看看。


本篇博客到这里就结束了,感谢各位的观看。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/73317.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp移动端图片比较器组件,仿英伟达官网rtx光追图片比较器功能

组件下载地址:https://ext.dcloud.net.cn/plugin?id22609 已测试h5和微信小程序,理论支持全平台 亮点: 简单易用 使用js计算而不是resize属性,定制化程度更高 组件挂在后可播放指示线动画,提示用户可以拖拽比较图片…

CI/CD—Jenkins实现自动构建Docker镜像运行Java程序

实现原理 1、Java代码中创建一个dockerfile文件 --> 2、代码上传至GitLab --> 3、Jenkins同步GitLab的代码进行构建生成jar --> 4、Jenkins将jar包和dockerfile文件传到测试服务器上 --> 5、在测试服务器上执行dockerfile构建jar镜像 --> 6、镜像构建完运行容器…

docker 搭建alpine下nginx1.26/mysql8.0/php7.4环境

docker 搭建alpine下nginx1.26/mysql8.0/php7.4环境 docker-compose.yml services:mysql-8.0:container_name: mysql-8.0image: mysql:8.0restart: always#ports:#- "3306:3306"volumes:- ./etc/mysql/conf.d/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro- ./var/log…

队列的简单例题

题目如下 模拟队列 首先你要明白队列的话 只有队尾才能进行新增,也就是入队 只有队首才能出队,也就是删除 队首队尾指针一开始默认都是0 相当于队列中一开始是有一个元素的就是 0的位置 队首指针head0 队尾指针tail0 1.入队也就是队尾要先赋值&#xf…

vue3+elementuiplus的table表格动态高度

table表格流体高度 1、前提 了解自定义指令、hooks 2、核心思路 通过自定义指令(new ResizeObserver)监听表格变化,然后通过hooks去更新表格高度。 3、核心代码 src/directives/resize.ts // import { debounce } from /utils;import { t…

Apache POI详解

目录 前言 Apache POI是一个强大的Java库,广泛用于处理Microsoft Office文档,包括Word、Excel和PowerPoint等。本文将详细介绍如何使用Apache POI库操作Word模板(包括替换占位符、操作表格)、将Word文档转换为PDF,以及…

AutoGen多角色、多用户、多智能体对话系统

2023-03-11-AutoGen 使用【autoGenchainlitdeepSeek】实现【多角色、多用户、多智能体对话系统】 1-核心思路 01)技术要点:autoGenchainlitdeepSeek02)什么是autoGen->autogen是微软旗下的多智能体的框架03)什么是chainlit-&g…

问deepseek: OpenFOAM并行分区后,是如何实现ldumatrix矩阵向量乘法计算逻辑的?

在OpenFOAM中,lduMatrix 是用于存储稀疏矩阵的类,支持并行计算。并行分区后,lduMatrix 的矩阵向量乘法通过以下步骤实现: 1. 矩阵分区 分区:将矩阵和向量分配到多个处理器上,每个处理器负责一部分。接口&…

数据类设计_图片类设计之4_规则类图形混合算法(前端架构)

前言 学的东西多了,要想办法用出来.C和C是偏向底层的语言,直接与数据打交道.尝试做一些和数据方面相关的内容 引入 接续上一篇,讨论图片类型设计出来后在场景中如何表达,以及图片的混合算法.前面的内容属于铺垫和基础,这篇内容和实际联系起来了. 背景图和前景图 这里笔者想先…

【openwebui 搭建本地知识库(RAG搭建本地知识库)】

安装准备 openwebui 这个本地安装之前写过使用python安装。也可以直接用docker 命令 docker run --rm -d \-p 3080:8080 \-p 3081:8081 \-e WEBUI_AUTHtrue \-e DEFAULT_LOCALEcn \-e GLOBAL_LOG_LEVEL"INFO" \-e AIOHTTP_CLIENT_TIMEOUT100 \--privilegedtrue \-…

Nginx的流式响应配置详解

现在大模型场景繁多,项目中涉及nginx转发大模型的流式数据时,需配置nginx的转发策略: location /streaming {proxy_pass http://backend_server;proxy_cache off; # 关闭缓存proxy_buffering off; # 关闭代理缓冲chunked_transfer_encoding …

git使用命令总结

文章目录 Git 复制创建提交步骤Git 全局设置:创建 git 仓库:已有仓库? 遇到问题解决办法:问题一先git pull一下,具体流程为以下几步: 详细步骤 Git 复制 git clone -b RobotModelSetting/develop https://gitlab.123/PROJECT/123.git创建提…

flutter 图片资源路径管理

1. 创建统一资源管理类 创建一个单独的 Dart 文件(比如 manager.dart),将所有图片路径集中管理。这样在引用图片时,不需要每次都手动输入完整路径,只需通过常量引用即可。 //manager.dartclass Manager { static co…

Android Retrofit 框架配置与构建模块深入源码分析(六)

一、引言 Retrofit 是一个在 Android 和 Java 开发中广泛使用的类型安全的 HTTP 客户端。它通过简洁的 API 设计,使得网络请求的处理变得高效且易于管理。配置与构建模块作为 Retrofit 的基础部分,承担着初始化和定制 Retrofit 实例的重要任务。开发者可…

80.Dictionary 字典 C#例子

使用 C# 中的 Dictionary 数据结构 在 C# 中&#xff0c;Dictionary<TKey, TValue> 是一个非常强大的数据结构&#xff0c;用于存储键值对。它提供了高效的查找、插入和删除操作&#xff0c;适用于需要快速访问数据的场景。本文将通过一个简单的示例&#xff0c;介绍如何…

tomcat负载均衡配置

这里拿Nginx和之前做的Tomcat 多实例来实现tomcat负载均衡 1.准备多实例与nginx tomcat单机多实例部署-CSDN博客 2.配置nginx做负载均衡 upstream tomcat{ server 192.168.60.11:8081; server 192.168.60.11:8082; server 192.168.60.11:8083; } ser…

C语言中scanf(“%c“,s)会出现的问题

scanf("%c%c", &word[0], &word[1]);的行为与输入缓冲区的内容密切相关。你提到输入ab后&#xff0c;word[0]是\n&#xff0c;这通常是因为输入缓冲区中残留了换行符&#xff08;\n&#xff09;。 一、原因分析 换行符残留 若在输入ab之前有其他输入操作&a…

SealOS部署k8s集群(单节点)

一、 先决条件 每个集群节点应该有不同的主机名。需要在 K8s 集群的第一个 master 节点上运行 sealos run 命令。建议使用干净的操作系统来创建集群。不要自己装 Docker&#xff01;支持大多数 Linux发行版&#xff0c;但内核版本建议5以上。例如&#xff1a;Ubuntu、CentOS、…

Linux 服务器安全配置:密码复杂度与登录超时设置

Linux服务器安全配置指南:密码复杂度与登录超时设置 一、密码复杂度设置 通过PAM模块pam_cracklib.so实现密码强度策略,配置文件: system-auth该文件主要用于定义系统范围内的认证策略,涵盖了用户登录、su 命令切换用户、sudo 权限提升等多种认证场景。当用户尝试进行系…

AI Agent开发框架分析:前端视角

1. Mastra (https://mastra.ai/docs) 优点&#xff1a; 提供直观的界面构建器&#xff0c;适合无代码/低代码开发支持JavaScript/TypeScript&#xff0c;可直接集成到前端项目可视化工作流设计&#xff0c;降低入门门槛内置多种UI组件&#xff0c;加速前端开发 缺点&#xf…