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

spring boot密码加密方式

1. BCrypt

原理

        BCrypt是一种专为密码哈希设计的算法,它被广泛认为是安全的选择之一。它不仅是一个单向函数(即只能加密不能解密),而且还内置了盐(salt)生成机制来防止彩虹表攻击。BCrypt的一个重要特点是它包含了一个可以调整的工作因子(或称为cost factor),这使得攻击者即使获得了数据库也难以通过暴力破解来解密密码。它具有以下特性:

  • 内置盐值:每次生成不同的盐值来防止彩虹表(彩虹表攻击是一种预计算攻击方法,攻击者事先计算大量可能密码的哈希值,并将其存储在一个表格中。当他们获得一个哈希后的密码时,可以通过查找这个预先构建的表来快速找出对应的明文密码。)攻击,这意味着即使两个用户的密码完全相同,他们的哈希结果也会因为不同的盐值而完全不同。因此,即使攻击者拥有非常大的彩虹表,也无法直接应用于另一个用户账户。
  • 可调的工作因子(cost factor):允许你根据硬件性能调整计算复杂度,从而增加暴力破解的成本。
  • 自适应性:随着硬件性能提升,可以增加工作因子以保持安全性。
配置细节与实例
引入依赖

确保你的pom.xml文件中包含以下依赖项:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
创建配置类

创建一个Spring配置类来定义PasswordEncoder Bean,并设置BCrypt的工作因子:

import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;@Configuration
public class SecurityConfig {@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder(12); // 可以调整cost factor,默认为10}
}
使用编码器

在服务层中使用这个编码器对用户密码进行编码和验证:

@Service
public class UserService {private final UserRepository userRepository;private final PasswordEncoder passwordEncoder;@Autowiredpublic UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {this.userRepository = userRepository;this.passwordEncoder = passwordEncoder;}public void registerUser(User user) {String hashedPassword = passwordEncoder.encode(user.getPassword());user.setPassword(hashedPassword);userRepository.save(user);}public boolean checkPassword(String rawPassword, String encodedPassword) {return passwordEncoder.matches(rawPassword, encodedPassword);}
}
注意事项
  • 工作因子的选择:应根据服务器性能选择适当的工作因子,既能保证安全性又不影响用户体验。
  • 盐值的安全性:虽然BCrypt会自动处理盐值,但了解其作用对于理解安全性很重要。

2. PBKDF2

原理

PBKDF2 (Password-Based Key Derivation Function 2) 是一种密钥派生函数,通过反复应用哈希函数来增加计算成本,使得暴力攻击更加困难。它可以接受一个盐值、迭代次数和其他参数。

配置细节与实例
引入依赖

确保已经包含了Spring Security的依赖项。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
创建自定义编码器

使用DelegatingPasswordEncoder来支持多种编码格式,其中包括PBKDF2:

import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;@Configuration
public class SecurityConfig {@Beanpublic PasswordEncoder passwordEncoder() {String idForEncode = "pbkdf2";Map<String, PasswordEncoder> encoders = new HashMap<>();encoders.put(idForEncode, new Pbkdf2PasswordEncoder("your-salt", 20000, 256));DelegatingPasswordEncoder delegatingPasswordEncoder = new DelegatingPasswordEncoder(idForEncode, encoders);delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(new Pbkdf2PasswordEncoder());return delegatingPasswordEncoder;}
}
使用编码器

在用户注册或更新密码时对明文密码进行编码,在登录验证时比较输入的密码与存储的哈希值。

注意事项
  • 迭代次数:应该足够大以确保安全性,但也要考虑服务器性能。
  • 盐值的管理:每个用户的盐值应当随机生成并妥善保存。

3. SCrypt

原理

SCrypt是一种内存密集型的哈希函数,旨在抵御GPU加速的暴力攻击。它需要大量的内存资源,因此对于硬件加速攻击具有很好的抵抗力。

配置细节与实例

由于Spring Security没有直接支持SCrypt,你需要引入第三方库,如scrypt库。

引入依赖

添加到pom.xml

<dependency><groupId>com.lambdaworks</groupId><artifactId>scrypt</artifactId><version>1.4.0</version>
</dependency>
创建自定义编码器

编写一个实现了PasswordEncoder接口的类来封装SCrypt逻辑:

import com.lambdaworks.scrypt.SCryptUtil;public class ScryptPasswordEncoder implements PasswordEncoder {@Overridepublic String encode(CharSequence rawPassword) {return SCryptUtil.scrypt(rawPassword.toString(), 16384, 8, 1);}@Overridepublic boolean matches(CharSequence rawPassword, String encodedPassword) {return SCryptUtil.check(rawPassword.toString(), encodedPassword);}
}
配置编码器
@Configuration
public class SecurityConfig {@Beanpublic PasswordEncoder passwordEncoder() {return new ScryptPasswordEncoder();}
}
注意事项
  • 参数调整:根据服务器硬件条件优化性能与安全性的平衡。
  • 内存消耗:考虑到SCrypt的高内存需求,可能不适合所有环境。

4. Argon2

深入原理

Argon2是现代且高效的哈希算法,特别适合于密码存储。Argon2提供了良好的安全性和性能,并且可以根据需要调整内存消耗、CPU时间和并行度。它有三个变种:Argon2d、Argon2i和Argon2id,其中Argon2id是最推荐使用的版本。

配置细节与实例
引入依赖

确保Spring Security的依赖项存在。

配置编码器
import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;@Configuration
public class SecurityConfig {@Beanpublic PasswordEncoder passwordEncoder() {return new Argon2PasswordEncoder(); // 使用默认参数}
}
高级配置

如果你想要调整Argon2的参数,可以这样做:

@Bean
public PasswordEncoder passwordEncoder() {return new Argon2PasswordEncoder(16, // salt长度32, // hash长度1,  // 并行度65536, // 内存成本(KB)3     // 迭代次数);
}
使用编码器

同样地,可以在服务层中使用此编码器来进行密码处理。

注意事项
  • 参数选择:直接影响到安全性和性能之间的权衡。
  • 默认变体:Argon2id是推荐的选择,因为它既抵抗时间-内存权衡攻击也抵抗侧信道攻击。

5. MD5(强烈不推荐)

原理

MD5是一种消息摘要算法,它可以将任意长度的数据转换成固定长度的128位(16字节)散列值。尽管MD5速度很快,但它已经被证明容易受到多种攻击,例如碰撞攻击(碰撞攻击是指攻击者尝试找到两个不同的输入,它们会产生相同的哈希输出(即碰撞)。对于大多数哈希函数来说,如果它们是安全的,则找到碰撞是非常困难的。然而,MD5 和 SHA-1 这样的早期哈希算法已经被证明容易受到碰撞攻击的影响)和预像攻击(预像攻击(Preimage Attack)是指攻击者尝试找到一个输入,使得其哈希值与给定的哈希输出相匹配),这使得它不再适合用于密码存储。

实现步骤
引入依赖

你可以使用Java自带的MessageDigest类来实现MD5哈希:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class MD5Hasher {public static String hashPassword(String password) {try {MessageDigest md = MessageDigest.getInstance("MD5");byte[] messageDigest = md.digest(password.getBytes());StringBuilder hexString = new StringBuilder();for (byte b : messageDigest) {String hex = Integer.toHexString(0xFF & b);if (hex.length() == 1) {hexString.append('0');}hexString.append(hex);}return hexString.toString();} catch (NoSuchAlgorithmException e) {throw new RuntimeException(e);}}
}
注意事项
  • 安全性问题:由于MD5的脆弱性,强烈建议不要使用它来存储密码。如果必须使用,至少要结合强盐值,并考虑迁移到更安全的算法如BCrypt、PBKDF2、SCrypt或Argon2。
  • 替代方案:对于新项目,务必选择上述提到的更安全的哈希算法。如果你的应用程序已经在使用MD5,应该尽快规划迁移路径,逐步升级到更安全的算法。

最佳实践

安全策略选择
  • 优先选择现代算法:BCrypt、PBKDF2、SCrypt和Argon2都是经过广泛审查并且被认为是安全的选择。
  • 避免使用过时算法:如MD5和SHA-1等早期算法已被证明存在安全隐患,不应该用于保护敏感信息。
  • 定期评估和更新:随着技术进步,新的漏洞可能会被发现,因此请定期检查并更新你的加密方案。
参数调整
  • 工作因子/迭代次数:这些参数决定了哈希函数的计算复杂度。选择适当的值可以在保证安全性的前提下不影响系统性能。
  • 内存成本和平行度:对于内存密集型算法(如SCrypt和Argon2),合理设置这些参数可以有效防御硬件加速攻击。
用户体验
  • 响应时间:在提高安全性的同时,也要考虑用户的等待时间。找到一个合理的平衡点,使安全措施不会成为用户体验的障碍。
  • 教育用户:鼓励用户采用强密码策略,如混合大小写字母、数字和特殊字符,并定期更改密码。
监控与测试
  • 全面测试:在生产环境中部署之前,务必进行全面的测试,确保所有功能正常运作。
  • 持续监控:上线后,持续监控系统性能,及时发现并解决潜在的问题,特别是那些可能影响到加密过程效率的因素。

相关文章:

spring boot密码加密方式

1. BCrypt 原理 BCrypt是一种专为密码哈希设计的算法&#xff0c;它被广泛认为是安全的选择之一。它不仅是一个单向函数&#xff08;即只能加密不能解密&#xff09;&#xff0c;而且还内置了盐&#xff08;salt&#xff09;生成机制来防止彩虹表攻击。BCrypt的一个重要特点是…...

springboot根据租户id动态指定数据源

代码地址 码云地址springboot根据租户id动态指定数据源: springboot根据租户id指定动态数据源,结合mybatismysql多数源下的事务管理 创建3个数据库和对应的表 sql脚本在下图位置 代码的执行顺序 先设置主数据库的数据源配置目标数据源和默认数据源有了主库的数据源&#xff…...

使用C语言编写UDP循环接收并打印消息的程序

使用C语言编写UDP循环接收并打印消息的程序 前提条件程序概述伪代码C语言实现编译和运行C改进之自由设定端口注意事项在本文中,我们将展示如何使用C语言编写一个简单的UDP服务器程序,该程序将循环接收来自指定端口的UDP消息,并将接收到的消息打印到控制台。我们将使用POSIX套…...

【AI】✈️问答页面搭建-内网穿透公网可访问!

目录 &#x1f44b;前言 &#x1f440;一、后端改动 &#x1f331;二、内网穿透 &#x1f49e;️三、前端改动 &#x1f379;四、测试 &#x1f4eb;五、章末 &#x1f44b;前言 小伙伴们大家好&#xff0c;上次本地搭建了一个简单的 ai 页面&#xff0c;实现流式输出问答…...

计算机毕业设计原创定制(免费送源码):NodeJS+MVVM+MySQL 樱花在线视频网站

目 录 摘要 1 1 绪论 1 1.1研究背景 1 1.2系统设计思想 1 1.3B/S体系工作原理 1 1.4node.js主要功能 2 1.5论文结构与章节安排 3 2 樱花在线视频网站分析 4 2.1 可行性分析 4 2.2 系统流程分析 4 2.2.1数据增加流程 5 2.3.2数据修改流程 5 2.3.3数据删除流程 5 …...

ECharts热力图-笛卡尔坐标系上的热力图,附视频讲解与代码下载

引言&#xff1a; 热力图&#xff08;Heatmap&#xff09;是一种数据可视化技术&#xff0c;它通过颜色的深浅变化来表示数据在不同区域的分布密集程度。在二维平面上&#xff0c;热力图将数据值映射为颜色&#xff0c;通常颜色越深表示数据值越大&#xff0c;颜色越浅表示数…...

【Lua热更新】下篇

上篇链接&#xff1a;【Lua热更新】上篇 文章目录 三、xLua热更新&#x1f4d6;1.概述&#x1f4da;︎2.导入xLua框架&#x1f516;3. C#调用Lua3.1Lua解析器3.2Lua文件夹的重定向3.3Lua解析器管理器3.4全局变量获取3.5全局函数获取3.6映射到List和Dictionary3.7映射到类3.8映…...

Facebook 与数字社交的未来走向

随着数字技术的飞速发展&#xff0c;社交平台的角色和形式也在不断演变。作为全球最大社交平台之一&#xff0c;Facebook&#xff08;现Meta&#xff09;在推动数字社交的进程中扮演了至关重要的角色。然而&#xff0c;随着互联网的去中心化趋势和新技术的崛起&#xff0c;Face…...

微信小程序实现二维码海报保存分享功能

首先在写这个二维码分享海报的时候试过很多方法&#xff0c;比如&#xff1a;canvas中的这个createCanvasContext创建上下文的方法&#xff0c;去网上一搜就是一大堆&#xff0c;但其实这个方法已经被废弃了。Canvas 实例&#xff0c;可通过 SelectorQuery 获取。这是绘制背景图…...

Android 搭建AIDL Client和Server端,双向通信

一、背景 使用AIDL,搭建Client和Server端,实现跨进程通讯,即两个应用之间可以相互通讯。这里列举AIDL实现的方式和需注意的细节&#xff0c;并附上源码。 二、实现方式 2.1 定义AIDL需要的接口,名字为xxx.aidl,Client和Server端 AIDL接口的包名和aidl文件必须一致&#xff0c…...

深度学习从入门到精通——图像分割实战DeeplabV3

DeeplabV3算法 参数配置关于数据集的配置训练集参数 数据预处理模块DataSet构建模块测试一下数据集去正则化模型加载模块DeepLABV3 参数配置 关于数据集的配置 parser argparse.ArgumentParser()# Datset Optionsparser.add_argument("--data_root", typestr, defa…...

STM32-笔记5-按键点灯(中断方法)

1、复制03-流水灯项目&#xff0c;重命名06-按键点灯&#xff08;中断法&#xff09; 在\Drivers\BSP目录下创建一个文件夹exti&#xff0c;在该文件夹下&#xff0c;创建两个文件exti.c和exti.h文件&#xff0c;并且把这两个文件加载到项目中&#xff0c;打开项目工程文件 加载…...

C++ 只出现一次的数字 - 力扣(LeetCode)

点击链接即可查看题目&#xff1a;136. 只出现一次的数字 - 力扣&#xff08;LeetCode&#xff09; 一、题目 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间…...

C++设计模式:享元模式 (附文字处理系统中的字符对象案例)

什么是享元模式&#xff1f; 享元模式是一个非常实用的结构型设计模式&#xff0c;它的主要目的是节省内存&#xff0c;尤其在需要创建大量相似对象时。 通俗解释&#xff1a; 想象我们在写一本书&#xff0c;每个字母都需要表示出来。如果每个字母都单独用对象表示&#xff…...

android EditText密码自动填充适配

android上的密码&#xff08;其实不仅仅是密码&#xff0c;可以是用户名也可以是邮箱&#xff09;自动填充&#xff0c;是需要考虑适配的。 官方文档&#xff1a;https://developer.android.com/identity/autofill/autofill-optimize?hlzh-cn 什么是自动填充 手机厂商一般会…...

LeetCode 刷题笔记

LeetCode 刷题笔记 1. 20241218 &#xff08;1&#xff09;2447 std::gcd是C17引入的一个函数&#xff0c;用于计算两个整数的最大公因数。位于<numeric>头文件中。 #include <iostream> #include <numeric> // std::gcdint main() {int a 36;int b 60…...

【Java基础面试题034】Java泛型擦除是什么?

回答重点 泛型擦除指的是Java编译器在编译时将所有泛型信息删除的过程&#xff0c;以确保与Java1.4及之前的版本保持兼容 泛型参数在运行时会被替换为其上界&#xff08;通常是Object&#xff09;&#xff0c;这样一来在运行时无法获取泛型的实际类型。 作用&#xff1a;泛型…...

使用ssh命令远程登录服务器的两种便捷方式:简化ssh命令、创建bat文件

1. 简化ssh命令 使用记事本打开该路径C:\Users\<你的用户名>\.ssh\下的config文件&#xff0c;粘贴以下代码&#xff1a; Host myserverHostName 192.168.1.1(这里换成你的ip地址)User your_username(这里换成你的用户名)Port 22保存文件后现在在cmd中直接输入ssh myserv…...

access数据库代做/mysql代做/Sql server数据库代做辅导设计服务

针对Access数据库、MySQL以及SQL Server数据库的代做和辅导设计服务&#xff0c;以下是一些关键信息和建议&#xff1a; 一、服务概述 这些服务通常包括数据库的设计、创建、优化、维护以及相关的编程和查询编写等。无论是Access这样的桌面关系数据库管理系统&#xff08;RDB…...

第十七届山东省职业院校技能大赛 中职组“网络安全”赛项任务书正式赛题

第十七届山东省职业院校技能大赛 中职组“网络安全”赛项任务书-A 目录 一、竞赛阶段 二、竞赛任务书内容 &#xff08;一&#xff09;拓扑图 &#xff08;二&#xff09;模块A 基础设施设置与安全加固(200分) &#xff08;三&#xff09;B模块安全事件响应/网络安全数据取证/…...

Android学习(五)-Kotlin编程语言-面向对象中的 继承-构造函数-接口三模块学习

首先&#xff0c;我们需要定义一个 Person 类&#xff1a; open class Person {var name ""var age 0fun eat() {println("$name is eating.")} } 注意&#xff0c;Person 类前面加上了 open 关键字&#xff0c;表示这个类可以被继承。在 Kotlin 中&am…...

滑动窗口 + 算法复习

维护一个满足条件的窗口大小&#xff0c;然后进行双指针移动 1.最长子串 题目链接&#xff1a;1.最长子串 - 蓝桥云课 #include<bits/stdc.h> #define int long long using namespace std; string s; int k; signed main() {int max_len0,left0;cin>>s>>k;…...

贪心算法 greedy

文章目录 参考贪心算法[Leetcode455 分发饼干](https://leetcode.cn/problems/assign-cookies/description/)分析题解 [Leetcode135 分发糖果](https://leetcode.cn/problems/assign-cookies/description/)分析题解 leetcode435无重叠区间分析题解 参考 https://github.com/ch…...

基于python的家教预约网站-家教信息平台系统

标题:基于 Python 的家教预约网站-家教信息平台系统 内容:1.摘要 本文介绍了一个基于 Python 的家教预约网站-家教信息平台系统。该系统旨在为学生和家长提供一个方便、高效的家教预约平台&#xff0c;同时也为家教老师提供一个展示自己教学能力和经验的机会。本文详细介绍了系…...

基于深度学习多图像融合的屏幕缺陷检测方案

公司项目&#xff0c;已申请专利。 深度学习作为新兴技术在图像领域蓬勃发展&#xff0c;因其自主学习图像数据特征的性能避免了人工设计算法的繁琐&#xff0c;精准的检测性能、高效的检测效率以及对各种不同类型的图像任务都有比较好的泛化性能&#xff0c;使得深度学习技术在…...

MySQL基础笔记(三)

在此特别感谢尚硅谷-康师傅的MySQL精品教程 获取更好的阅读体验请前往我的博客主站! 如果本文对你的学习有帮助&#xff0c;请多多点赞、评论、收藏&#xff0c;你们的反馈是我更新最大的动力&#xff01; 创建和管理表 1. 基础知识 1.1 一条数据存储的过程 存储数据是处理数…...

【JetPack】WorkManager笔记

WorkManager简介&#xff1a; WorkManager 是 Android Jetpack 库中的一个重要组件。它用于处理那些需要在后台可靠执行的任务&#xff0c;这些任务可以是一次性的&#xff0c;也可以是周期性的&#xff0c;甚至是需要满足特定条件才执行的任务。例如&#xff0c;它可以用于在后…...

docker 安装 ftp

前言 经多次测试 不知道为什么 必须添加被动模式跟端口才可以 连接成功&#xff0c;有知道为什么可以评论下 下载镜像 docker pull fauria/vsftpd启动ftp 服务 参考链接 docker run -d -v /etc/localtime:/etc/localtime:ro -v /home/dr/data/ftp:/home/vsftpd \ -e "…...

5.C语言内存分区-堆-栈

目录 内存分区 运行之前 代码区 全局初始化数据区 、静态数据区 (data) 未初始化数据区(bss&#xff08;Block Started by Symbol&#xff09;区) 总结 运行之后 代码区 &#xff08;text segment&#xff09; 未初始化数据区(bss) 全局初始化数据区&#xff0c;静态…...

传统CV算法——基于opencv的答题卡识别判卷系统

基于OpenCV的答题卡识别系统&#xff0c;其主要功能是自动读取并评分答题卡上的选择题答案。系统通过图像处理和计算机视觉技术&#xff0c;自动化地完成了从读取图像到输出成绩的整个流程。下面是该系统的主要步骤和实现细节的概述&#xff1a; 1. 导入必要的库 系统首先导入…...