【SpringBoot】随机盐值+双重SHA256加密实战

目录:

1.SHA-256和随机盐值

2.前端实现

3.后端实现

1.SHA-256和Salt

1.1.什么是SHA-256

SHA-256是一种信息摘要算法,也是一种密码散列函数。对于任意长度的消息,SHA256都会产生一个256bit长的散列值(哈希值),用于确保信息传输完整一致,称作消息摘要。这个摘要相当于是个长度为32个字节的数组,通常用一个长度为64的十六进制字符串来表示。

SHA-256的具备以下几个关键特点:

  1. 固定长度输出:无论输入数据的大小,SHA-256都会产生一个256位(32字节)的固定长度散列值。
  2. 不可逆性:SHA-256的设计使得从生成的散列值无法还原原始输入数据。这种不可逆性在安全性上是非常重要的。
  3. 抗碰撞性:找到两个不同的输入数据具有相同的散列值(碰撞)是极其困难的。虽然理论上碰撞可能发生,但SHA-256被设计得非常抗碰撞。

除了SHA-256之外,还有一个密码散列函数MD5,过去也常被用于密码加密,但MD5在安全性上低于SHA-256,现在已经很少用于密码加密了,本文不做考虑。

SHA-256 和 MD5 的比较:

特性SHA-256MD5
输出长度256 位(64 个十六进制字符)128 位(32 个十六进制字符)
安全性
计算速度较慢
抗碰撞能力
应用场景数据完整性校验、数字签名、密码存储、区块链曾用于文件校验、密码存储
推荐使用

1.2.什么是随机盐值

盐值(salt) 是一种在密码学和安全计算中常用的随机数据,用于增强密码散列的安全性。

随机盐值(random salt)是一种用于增强密码散列安全性的技术。它是一个随机生成的数据块,在将密码输入散列函数之前,将盐值与密码组合。通过引入随机盐值,可以有效地防止彩虹表攻击和相同密码散列值重复的问题。

盐值的作用:

  1. 防止彩虹表攻击: 彩虹表是一个预计算的哈希值数据库,用于快速查找常见密码的哈希值。通过在密码哈希之前加入随机盐值,即使密码相同,其最终的哈希值也会不同,从而使彩虹表无效。
  2. 避免散列值重复: 如果两个用户使用相同的密码,在没有盐值的情况下,他们的哈希值会相同。加入盐值后,即使密码相同,生成的哈希值也会不同,这有助于防止攻击者通过观察哈希值来推测用户是否使用了相同的密码。
  3. 增加攻击难度: 盐值增加了密码哈希的复杂性。即使攻击者获取了存储的哈希值和盐值,他们仍需对每个盐值进行单独的暴力破解,显著增加了破解的时间和计算成本。

1.3.如何进行加密操作

本文采用的加密方式是在前端采用md加密防止明文传输,后端对密码二次加密后再进行随机盐值的混入。

2.前端实现

引入md5.min.js

<!DOCTYPE html>
<html lang="en"xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>登录</title><!-- jquery --><script type="text/javascript" th:src="@{/js/jquery.min.js}"></script><!-- bootstrap --><link rel="stylesheet" type="text/css" th:href="@{/bootstrap/css/bootstrap.min.css}"/><script type="text/javascript" th:src="@{/bootstrap/js/bootstrap.min.js}"></script><!-- jquery-validator --><script type="text/javascript" th:src="@{/jquery-validation/jquery.validate.min.js}"></script><script type="text/javascript" th:src="@{/jquery-validation/localization/messages_zh.min.js}"></script><!-- md5.js --><script type="text/javascript" th:src="@{/js/md5.min.js}"></script><!-- common.js --><script type="text/javascript" th:src="@{/js/common.js}"></script>
</head>
<body>
<form name="loginForm" id="loginForm" method="post" style="width:50%; margin:0 auto"><h2 style="text-align:center; margin-bottom: 20px">用户登录</h2><div class="form-group"><div class="row"><label class="form-label col-md-4">请输入手机号码</label><div class="col-md-5"><input id="mobile" minlength="11" maxlength="11" name="mobile" class="form-control" type="text" placeholder="手机号码" required="true"/></div></div></div><div class="form-group"><div class="row"><label class="form-label col-md-4">请输入密码</label><div class="col-md-5"><input id="password" name="password" class="form-control" type="password" placeholder="密码" required="true" /></div></div></div><div class="row"><div class="col-md-5"><button class="btn btn-primary btn-block" type="reset" onclick="reset()">重置</button></div><div class="col-md-5"><button class="btn btn-primary btn-block" type="submit" onclick="login()">登录</button></div></div>
</form>
</body>
<script>function login() {$("#loginForm").validate({submitHandler: function (form) {doLogin();}});}function doLogin() {var inputPass = $("#password").val();var salt = "1a2b3c4d";var str = "" + salt.charAt(0) + salt.charAt(2) + inputPass + salt.charAt(5) + salt.charAt(4);var password = md5(str);$.ajax({url: "/login/doLogin",type: "POST",data: {mobile: $("#mobile").val(),password: password},success: function (data) {layer.closeAll();if (data.code == 200) {layer.msg("成功");console.log(data);document.cookie = "userTicket=" + data.object;window.location.href = "/goods/toList";} else {layer.msg(data.message);}},error: function () {layer.closeAll();}});}
</script>
</html>

3.后端实现

3.1.导入Maven依赖

 <dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.15</version>
</dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version>
</dependency>

3.2.密码加密

3.2.1.密码加盐

首先使用Apache的RandomStringUtils工具类,生成16位的盐值。然后将盐拼接到明文后面,进行SHA256加密。

这个加密后的SHA256是个固定64长度的字符串。

// 生成一个16位的随机数,也就是盐
String salt = RandomStringUtils.randomAlphanumeric(16);// 将盐拼接到明文后,并生成新的sha256码
String sha256Hex = DigestUtils.sha256Hex(password + salt);
3.2.2.随机盐值混合

加盐后的SHA256码长度为80位,这里我们采用的盐值混合规则:将SHA-256散列值的每四个字符中间插入一个盐值字符,依次交替排列。

// 将盐混到新生成的SHA-256码中,之所以这样做是为了后期解密,校验密码
StringBuilder sb = new StringBuilder(80); // SHA-256是64个字符,加16个字符的盐,总共80个字符
for (int i = 0; i < 16; i++) {sb.append(sha256Hex.charAt(i * 4));sb.append(salt.charAt(i));sb.append(sha256Hex.charAt(i * 4 + 1));sb.append(sha256Hex.charAt(i * 4 + 2));sb.append(sha256Hex.charAt(i * 4 + 3));
}
return sb.toString();

这样就完成了加密的操作:密码加盐 + 盐值混合

3.3.密码解密

3.3.1.提取盐值和加盐密码

按照加密时采用的规则:将SHA-256散列值的每四个字符中间插入一个盐值字符,依次交替排列。

我们可以将盐值和加盐后的SHA-256码

// 提取盐值和加盐后的SHA-256码
StringBuilder sb1 = new StringBuilder(64);
StringBuilder sb2 = new StringBuilder(16);for (int i = 0; i < 16; i++) {sb1.append(encrypted.charAt(i * 5));sb1.append(encrypted.charAt(i * 5 + 2));sb1.append(encrypted.charAt(i * 5 + 3));sb1.append(encrypted.charAt(i * 5 + 4));sb2.append(encrypted.charAt(i * 5 + 1));
}String sha256Hex = sb1.toString();
String salt = sb2.toString();
3.3.2.比较密码

最后,将取出的盐值与原始密码再次加盐,再次得到加盐密码,与sha256Hex比较即可判断密码是否相同。

// 比较二者是否相同
return  DigestUtils.sha256Hex(password + salt).equals(sha256Hex);

3.4.完整工具类

public class SHA256Util {/*** 加密* 生成盐和加盐后的SHA-256码,并将盐混入到SHA-256码中,对SHA-256密码进行加强**/public static String encryptPassword(String password) {// 生成一个16位的随机数,也就是盐String salt = RandomStringUtils.randomAlphanumeric(16);// 将盐拼接到明文后,并生成新的sha256码String sha256Hex = DigestUtils.sha256Hex(password + salt);// 将盐混到新生成的SHA-256码中,之所以这样做是为了后期解密,校验密码StringBuilder sb = new StringBuilder(80); // SHA-256是64个字符,加16个字符的盐,总共80个字符for (int i = 0; i < 16; i++) {sb.append(sha256Hex.charAt(i * 4));sb.append(salt.charAt(i));sb.append(sha256Hex.charAt(i * 4 + 1));sb.append(sha256Hex.charAt(i * 4 + 2));sb.append(sha256Hex.charAt(i * 4 + 3));}return sb.toString();}/*** 解密* 从混入盐的SHA-256码中提取盐值和加盐后的SHA-256码**/public static boolean verifyPassword(String password, String encrypted) {// 提取盐值和加盐后的SHA-256码StringBuilder sb1 = new StringBuilder(64);StringBuilder sb2 = new StringBuilder(16);for (int i = 0; i < 16; i++) {sb1.append(encrypted.charAt(i * 5));sb1.append(encrypted.charAt(i * 5 + 2));sb1.append(encrypted.charAt(i * 5 + 3));sb1.append(encrypted.charAt(i * 5 + 4));sb2.append(encrypted.charAt(i * 5 + 1));}String sha256Hex = sb1.toString();String salt = sb2.toString();// 比较二者是否相同return  DigestUtils.sha256Hex(password + salt).equals(sha256Hex);}
}

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

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

相关文章

插件更新了!

最近花了点时间&#xff0c;给网页插件添加了新功能&#xff0c;下面简单给大家介绍一下如何使用 我们安装好插件后&#xff0c;进入网页就可以看到一个带logo的按钮了&#xff0c;我们可以点一下就可以跳出快捷操作 不同页面点击会出现不同的功能&#xff0c;大家可以根据自己…

dy商品评论采集

摘要 本文将详细介绍如何通过抖音商品评论采集来获取精准的用户反馈&#xff0c;从而优化产品和营销策略。通过这个指南&#xff0c;您将学会如何设置评论采集系统&#xff0c;分析用户评论数据&#xff0c;以及如何利用这些数据来吸引更多粉丝&#xff0c;增加商品销量。 返…

跨境传输需要遵守哪些准则,如何做到有效管控?

在全球化的商业环境中&#xff0c;跨国企业面临着数据跨境传输的挑战。随着业务的扩展&#xff0c;企业需要在不同国家和地区之间高效、安全地传输大量数据。选择合适的跨境传输方案对于保障数据安全、提高业务效率、遵守法律法规至关重要。 跨境传输数据需要遵守的准则和规定主…

Nginx:关于实现跨域代理

运维专题 Nginx&#xff1a;关于实现跨域代理 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.ne…

数据赋能(142)——开发:数据合并——技术方法、主要工具

技术方法 数据合并的技术方法主要包括以下几种&#xff1a; 轴向连接&#xff08;Concatenation&#xff09;&#xff1a; 使用pd.concat()函数&#xff0c;沿一个轴&#xff08;通常是行或列&#xff09;将多个DataFrame对象连接在一起&#xff0c;形成一个新的DataFrame对…

html自学笔记与面试会问到问题

第一章 1.1什么是JavaScript&#xff1f; 一各跨平台的脚本语言1.2ECMA特点&#xff1a; 由三大部分组成&#xff1a;核心语法(关键字、核心对象、语法)、DOM、BOM1.3 取余运算&#xff08;又叫取模运算&#xff09;&#xff1a; 取余&#xff1a;整除后&#xff0c;除不尽的…

发那科机床联网串口配置

本文章仅针对无网口&#xff0c;需要通过串口输出采集数据情况。跟这篇文章互为参考&#xff0c;一个理论&#xff0c;一个实战。 Fanuc DPRNT宏程序串口采集-CSDN博客 一、禁用机器串口监控 选择System、monit 二、设置参数可写 在MDI模式中字符面板上按OFS/SET键,连按致屏…

终于搞定了通过两路蓝牙接收数据

一直想做无线传感器&#xff0c;通过蓝牙来接收数据&#xff0c;无奈因为arduino接收串口数据的一些问题&#xff0c;一直搁到现在。因为学校里给学生开了选修课&#xff0c;所以手边有一些nano和mega可以使用&#xff0c;所以就做了用两个nano加上两个蓝牙模块来发射数据&…

经常用借呗和花呗对征信有影响吗?

说起支付宝里的花呗和借呗&#xff0c;大伙儿肯定都不陌生&#xff0c;它们俩就像是支付宝里的信用贷款双胞胎&#xff0c;名字相近&#xff0c;性格却大相径庭。现在&#xff0c;这俩兄弟都乖乖地接入了央行的征信大家庭&#xff0c;你的每一次使用&#xff0c;都会被记录得清…

GEE代码实例教程详解:湖泊水位变化监测

简介 本篇博客将介绍如何使用Google Earth Engine (GEE) 对湖泊水位变化进行监测。通过MODIS数据集&#xff0c;我们可以识别2001年和2023年的湖泊范围&#xff0c;并计算湖泊的高程变化。 背景知识 MODIS数据集 MODIS/061/MOD09Q1数据集提供了MODIS的地表反射数据&#xf…

DDD架构

1.DDD架构的概念&#xff1a; 领域驱动设计&#xff08;Domain-Driven Design, DDD&#xff09;是一种软件设计方法&#xff0c;旨在将软件系统的设计和开发焦点集中在领域模型上&#xff0c;以解决复杂业务问题 2.DDD架构解决了什么问题: 在以前的mvc架构种&#xff0c;三层结…

产品经理-交互设计动手实践(11)

业内有很多画交互的工具&#xff0c;这里不过多介绍&#xff0c;互联网公司最常用的工具是Axure,墨刀,蓝湖,小瀑 它是一个专业的快速原型设计工具&#xff0c;使用它能够快速创建线框图、流程图、原型和规格说明文档。 它能快速、高效地创建原型&#xff0c;同时支持多人协作设…

华为HCIP Datacom H12-821 卷30

1.单选题 以下关于OSPF协议报文说法错误的是? A、OSPF报文采用UDP报文封装并且端口号是89 B、OSPF所有报文的头部格式相同 C、OSPF协议使用五种报文完成路由信息的传递 D、OSPF所有报文头部都携带了Router-ID字段 正确答案&#xff1a;A 解析&#xff1a; OSPF用IP报…

iOS 开发中不常见的专业术语

乐此不疲地把简单的问题复杂化&#xff0c;并把这种XX行为叫作专业 APM 在 iOS 开发中&#xff0c;APM 代表 Application Performance Management&#xff08;应用性能管理&#xff09;。APM 是一套监控和管理应用程序性能的工具和技术&#xff0c;旨在确保应用程序运行平稳、…

【人工智能】-- 法律与伦理

个人主页&#xff1a;欢迎来到 Papicatch的博客 课设专栏 &#xff1a;学生成绩管理系统 专业知识专栏&#xff1a; 专业知识 文章目录 &#x1f349;引言 &#x1f349;伦理问题 &#x1f348;隐私泄露问题 &#x1f34d;人工智能与隐私泄露的紧密关联 &#x1f34d;数…

上海慕尼黑电子展开展,启明智显携物联网前沿方案亮相

随着科技创新的浪潮不断涌来&#xff0c;上海慕尼黑电子展在万众瞩目中盛大开幕。本次展会汇聚了全球顶尖的电子产品与技术解决方案&#xff0c;成为业界瞩目的焦点。启明智显作为物联网彩屏显示领域的佼佼者携产品亮相展会&#xff0c;为参展者带来了RTOS、LINUX全系列方案及A…

测试工作流程

基础 测试流程 1)需求研读&#xff1a; 通读需求了解需求整体内容&#xff0c;然后精读需求理解需求的每⼀个业务逻辑&#xff0c;每⼀句话的意思。在研读需求过程中的记录问题&#xff0c;然后通过百度&#xff0c;AI⼯具&#xff0c;CSDN社区&#xff0c;咨询朋友&#xf…

鸿蒙 arkts 实现手机号中间四位隐藏, 可以使用 substring [ 简单适用新手 ]

1, 看效果 2, 直接cv代码就可以 Preview Entry Component struct Setting {Statephone:string 15555555555maskPhoneNumber(phone:string){const start phone.substring(0,3)const end phone.substring(7)return ${start}****${end}}build() {Column(){Text(this.maskPhon…

Leetcode2542-最大子序列的分数

1.问题转换 首先明确题意&#xff0c;要选取的值和num1&#xff0c;num2两个数组都有关&#xff0c;但是num1中选取的是k个数&#xff0c;num2中选取的是1个数&#xff0c;显然num2中的数所占的权重较大&#xff08;对结果影响较大&#xff09;&#xff0c;所以我们就可以对nu…

【Java探索之旅】多态:向上下转型、多态优缺点、构造函数陷阱

文章目录 &#x1f4d1;前言一、向上转型和向下转型1.1 向上转型1.2 向下转型 二、多态的优缺点2.1 多态优点2.2 多态缺陷 三、避免避免构造方法中调用重写的方法四、好的习惯&#x1f324;️全篇总结 &#x1f4d1;前言 在面向对象编程中&#xff0c;向上转型和向下转型是常用…