Spring security 密码加密使用

一、密码加密

    2011年12月21日,有人在网络上公开了一个包含600万个CSDN 用户资料的数据库,数据全部为明文储存,包含用户名、密码以及注册邮箱。事件发生后CSDN 在微博、官方网站等渠道发出了声明、解释说此数据库系2009 年备份所用,因不明原因泄漏,已经向警方报案,后又在官网发出了公开道歉信。在接下来的十多天里,金山,网易,京东、当当、新等多家公司被卷入到这次事件中。整个事件中最触目惊心的莫过于CSDN把用户密码明文存储,由于很多用户是多个网站共用一个密码,因此一个网站密码泄漏就会造成很大的安全患。由于有了这么多前车之鉴、我们现在做系统时,密码都要加密处理。

在前面的案例中,凡是涉及密码的地方,我们都采用明文存储,在实际项目中这肯定是不可取的,因为这会带来极高的安全风险。在企业级应用中,密码不仅需要加密,还需要加大程度地保证密码安全,防止用户信息泄露;

二、密码加密的常见方案

   2.1.1 Hash 算法

    最早我们使用类似 SHA-256、SHA-512、MD5等这样的单向 Hash 算法。用户注册成功后,保存在数据库中不再是用户的明文密码,而是经过 SHA-256 加密计算的一个字行串当用户进行登录时,用户输入的明文密码用SHA-256 进行加密,加密完成之后,再和存储在数据库中的密码进行比对,进而确定用户登录信息是否有效。如果系统遭遇攻击,最多也只是存储在数据库中的密文被泄漏。

这样就绝对安全了吗?由于彩表这种攻击方式的存在以及随着计算机硬件的发展,每利执行数十亿次 HASH计算已经变得轻轻松松,这意味着即使给密码加密加盐也不再安全;

2.1.2 单向自适应函数

   在Spring Security 中,我们现在是用一种自适应单向函数(Adaptive One-way Functions)来处理密码问题,这种自适应单向函数在进行密码匹配时,会有意占用大量系统资源(例如CPU、内存等),这样可以增加恶意用户攻击系统的难度。在Spring Securiv 中,开发者可以通过bcrypt、PBKDF2、sCrvpt以及argon2 来体验这种自适应单向函数加密。由于自适应单向函数有意占用大量系统资源,因此每个登录认证请求都会大大降低应用程序的性能,作是SpringSecuity不会采取任何措施来提高密码验证速度,因为它正是通过这种方式来增强系统的安全性。

三、PasswordEncoder 密码加密器

Spring Security的PasswordEncoder接口用于执行密码的单向转换,以允许安全地存储密码。鉴于PasswordEncoder是一种单向转换,当密码转换需要双向转换时(即存储用于向数据库进行身份验证的凭据),就不打算这样做。通常,PasswordEncoder用于存储在身份验证时需要与用户提供的密码进行比较的密码。

3.1 BCryptPasswordEncoder

   BCryptPasswordEncoder使用 bcrypt 算法对密码进行加密,为了提高密码的安全性,bcrypt算法故意降低运行速度,以增强密码破解的难度。同时 BCryptP asswordEncode“为自己带盐”开发者不需要额外维护一个“盐”字段,使用BCryptPasswordEncoder 加密后的字符串就已经“带盐”了,即使相同的明文每次生成的加密字符串都不相同。

3.2 Argon2PasswordEncoder

  Argon2PasswordEncoder 使用Argon2 算法对密码进行加密,Argon2 曾在 PassworHashing Competition 竞赛中获胜。为了解决在定制硬件上密码容易被破解的问题Argon2也是故意降低运算速度,同时需要大量内存,以确保系统的安全性。

3.3 Pbkdf2PasswordEncoder

  Pbkdf2PasswordEncoder使用PBKDF2算法对密码进行加密和前面几种类似,PBKDF2算法也是一种故意降低运算速度的算法,当需要FIPS(Federal Information ProcessingStandard美国联邦信息处理标准)认证时,PBKDF2 算法是一个很好的选择。

3.4 SCryptPasswordEncoder

  SCryptPasswordEncoder 使用scrypt 算法对密码进行加密,和前面的几种类似,serypt也是一种故意降低运算速度的算法,而且需要大量内存。

3.5 默认的几种加密方式

@Test

public void test() f

//1 .BCryptPasswordEncoder

BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder()

System.out.println(bCryptPasswordEncoder.encode( "123"));

//2.Pbkdf2PasswordEncode

Pbkdf2PasswordEncoder pbkdf2PasswordEncoder = new Pbkdf2PasswordEncoder()

System.out.println(pbkdf2PasswordEncoder.encode("123"));

//3.SCryptPasswordEncoder //需要额外引入依赖

SCryptPasswordEncoder sCryptPasswordEncoder = new SCryptPasswordEncoder()

System.out.println(sCryptPasswordEncoder.encode("123")):

1/4.Argon2PasswordEncoder //需要额外入依邮

Argon2PasswordEncoder argon2PasswordErcoder = new Argon2PasswordEncoder():

System.out.println(argon2PasswordEncoder.encode("123"));

}


四、DelegatingPasswordEncoder 密码加密器代理

   在Spring Security 5.0之前,默认的PasswordEncoder是NoOpPasswordEncoder,它需要纯文本密码。根据密码历史部分,您可能会认为默认的PasswordEncoder现在类似于BCryptPasswordEncoder。然而,这忽略了三个现实世界的问题:

1、有许多使用旧密码编码的应用程序无法轻松迁移

2、密码存储的最佳做法将再次更改

3、作为一个框架,Spring Security不能频繁进行破坏性更改

相反,Spring Security引入了DelegatingPasswordEncoder,通过以下方式解决了所有问题:

1、确保使用当前的密码存储建议对密码进行编码

2、允许验证现代和传统格式的密码

3、允许将来升级编码

4.1 创建一个DelegatingPasswordEncoder

PasswordEncoder passwordEncoder =
PasswordEncoderFactories.createDelegatingPasswordEncoder();
String idForEncode = "bcrypt";
Map encoders = new HashMap<>();
encoders.put(idForEncode, new BCryptPasswordEncoder());
encoders.put("noop", NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
encoders.put("sha256", new StandardPasswordEncoder());PasswordEncoder passwordEncoder =
new DelegatingPasswordEncoder(idForEncode, encoders);

4.2 为什么在密码前面加上{noop}其他前缀就可以匹配

 4.2.1 源码部分:WebSecurityConfigurerAdapter

总结:通过源码我们看到当我们加上了noop 最后会调用NoOpPasswordEncoder 实现,直接通过equals 判断,直接字符串比较得到是否相等

4.3.2 密码在何处使用

总结: 通过源码分析得知如果在工厂中指定了PasswordEncoder,就会使用指定PasswordEncoder.  否则就会使用默认DelegatingPasswordEncoder。


五、如何使用 PasswordEncoder

我们可以使用动态配置和固定配置两种模式,默认就是动态配置模式,什么都不写

5.1 使用动态密码配置

实际上就写自己的加密方式,不要手动创建 PasswordEncoder 的bean对象就可以了

@SpringBootTest
public class SecurityConfigurationTest {@Testpublic void userDetailsService() {Pbkdf2PasswordEncoder encoder = new Pbkdf2PasswordEncoder();String encode = encoder.encode("123456");System.out.println(encode);}
}
得到密码:b694b853c2a55717df36e90fd46dae9bbaad46461f9c8bcc3564ef06908e77400f35f3184c11150d/***  自定义数据源* @return*/@Beanpublic UserDetailsService userDetailsService() {InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();userDetailsManager.createUser(User.withUsername("test").password("{pbkdf2}b694b853c2a55717df36e90fd46dae9bbaad46461f9c8bcc3564ef06908e77400f35f3184c11150d").authorities("admin").build());return userDetailsManager;
}

5.1.1 测试登录是否能匹配

5.2 使用固定密码加密方案

系统使用指定的某一种加密方案,不基于动态配置

5.2.1 注入加密编码器

 @Beanpublic PasswordEncoder passwordEncoder() {return new Pbkdf2PasswordEncoder();
}

5.2.2 去掉密码的前缀 {pbkdf2}

 /***  自定义数据源* @return {pbkdf2}*/@Beanpublic UserDetailsService userDetailsService() {InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();userDetailsManager.createUser(User.withUsername("test").password("b694b853c2a55717df36e90fd46dae9bbaad46461f9c8bcc3564ef06908e77400f35f3184c11150d").authorities("admin").build());return userDetailsManager;}

5.2.3 源码实现


六、密码自动升级

spring security 基于安全考虑,设计了一套能自动进行升级的配置,只需要实现UserDetailsPasswordService 就会更新

通过源码分析我们得知,需要实现UserDetailsPasswordService 方法,而且密码必须是{noop}12345 这种模式

6.1 代码配置

@Bean
public UserDetailsService userDetailsService() {InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();userDetailsManager.createUser(User.withUsername("test").password("{noop}12345").authorities("admin").build());return userDetailsManager;
}

6.2 源码

更新后,将user密码重新赋值

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

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

相关文章

外包干了2年,女朋友跑了...

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 简单的说下&#xff0c;我大学的一个同学&#xff0c;毕业后我自己去了自研的公司&#xff0c;他去了外包&#xff0c;快两年了我薪资、技术各个方面都有了很大的…

Salesforce篇——如何在lightning页面添加ListviewButton使用lwc组件

1.创建lwc组件&#xff0c;用于展示listview已选数据&#xff1a; html&#xff1a; <template><lightning-card title"Selected Records"><p>Selected Record IDs: {selectedIds}</p><lightning-button label"返回" onclick…

Spring中Bean的生命周期管理

Spring框架中的Bean生命周期是指从创建到销毁的整个过程。在这个过程中&#xff0c;Spring容器会负责管理Bean的状态和行为。以下是Spring中Bean生命周期的详细解释&#xff1a; 实例化&#xff1a;Spring容器根据Bean的定义信息&#xff0c;通过反射机制创建Bean对象。 设置属…

“阉割版”ADS还能遥遥领先吗?

文/王俣祺 导语&#xff1a;随着特斯拉FSD一次又一次的“入华无门”&#xff0c; 让国内车企智能驾驶的“内卷”之争迎来了喘息的余地&#xff0c;而“端到端”也成为现如今市场上的首要研发目标。早在今年4月份&#xff0c;华为就宣布其研发的HUAWEI ADS 3.0已经采用了最新的端…

Java-数据结构-包装类和认识泛型 !!!∑(゚Д゚ノ)ノ

目录&#xff1a; 一、包装类&#xff1a; 1、基本数据类型所对应的包装类&#xff1a; 2、装箱和拆箱&#xff1a; 二、 泛型&#xff1a; 1、什么是泛型&#xff1a; 2、语法&#xff1a; 三、泛型类的使用&#xff1a; 四、裸类型&#xff1a; 五、泛型的擦除机制&…

[oeasy]python031_[趣味拓展]unix起源_Ken_Tompson_Ritchie_multics

[趣味拓展]unix起源_Ken_Tompson_Ritchie_multics &#x1f94b; 回忆上次内容 上次 动态设置了 断点 断点 可以把代码 切成一段一段的可以 更快地调试 调试的目的 是 去除 bug 别害怕 bug 一步步 总能找到 bug这 就是 程序员基本功 调试 debug 在bug出现的时候 甚至…

Python 变量类型

Python 变量类型 变量赋值 多个变量赋值 标准数据类型 Python 数字 Python字符串 Python列表 Python 元组 Python 字典 Python数据类型转换 Python 变量类型 变量是存储在内存中的值&#xff0c;这就意味着在创建变量时会在内存中开辟一个空间。 基于变量的数据类型…

【视频讲解】主成分分析原理与水果成熟数据实例:Python中PCA-LDA 与卷积神经网络CNN...

全文链接&#xff1a;https://tecdat.cn/?p37450 分析师&#xff1a;Shixian Ding 主成分分析&#xff08;PCA&#xff09;作为数据科学中用于可视化和降维的重要工具&#xff0c;在处理具有大量特征的数据集时非常有用。就像我们难以找到时间阅读一本 1000 页的书&#xff0…

实现流程化办公,可专注于开源可视化报表设计器!

近日&#xff0c;有很多粉丝和朋友们会问我们关于低代码技术平台、开源可视化报表设计器的相关内容和问题。其实&#xff0c;在流程化办公新时代&#xff0c;愿意启用新软件平台的客户朋友会收获市场红利&#xff0c;也会站在前沿之地上斩获更多市场份额。今天我们就一起来了解…

随机森林与线性回归

集成学习方法之随机森林 集成学习&#xff08;Ensemble Learning&#xff09;是一种通过组合多个分类器来提高预测性能的方法。主要分为三种类型:Bagging、Boosting和Stacking。以下是集成学习的基本步骤和概念&#xff1a; 1数据采样&#xff1a;从训练集中有放回地随机抽取…

【渗透测试】ATTCK靶场一,phpmyadmin,域渗透,内网横向移动攻略

前言 博客主页&#xff1a;h0ack1r丶羽~ 从0到1~ VulnStack&#xff0c;作为红日安全团队匠心打造的知识平台&#xff0c;其独特优势在于全面模拟了国内企业的实际业务场景&#xff0c;涵盖了CMS、漏洞管理及域管理等核心要素。这一设计理念源于红日安全团队对ATT&CK红队评…

斯坦福大学cs231n (图像分类)

1.介绍 当作图像分类时&#xff0c;分类系统接收一些分类图像&#xff0c;比如猫咪。并且系统清楚了一些已经确定了分类或者标签的集合。那么&#xff0c;计算机的工作就是根据图片&#xff0c;给他分配一些固定的分类或者标签。 对于一个计算机来说&#xff0c;这是一个非常…

springsecurity 在web中如何获取用户信息(后端/前端)

一、SecurityContextHolder 是什么 SecurityContextHolder用来获取登录之后用户信息。Spring Security 会将登录用户数据保存在Session中。但是&#xff0c;为了使用方便,Spring Security在此基础上还做了一些改进&#xff0c;其中最主要的一个变化就是线程绑定。当用户登录成功…

FastGPT如何增减用户

背景 开源版本的FastGPT默认只有一个超级用户root&#xff0c;为了更好地管理应用和知识库&#xff0c;可以通过操作MongoDB数据库来增加新的用户和团队。 所需环境 已安装并运行的FastGPT实例MongoDB客户端工具&#xff08;如Mongo Shell或Robo 3T等&#xff09; 操作步骤…

数据库三大范式

三大范式 一种数据库设计理念&#xff0c;意义在于降低耦合 写代码 高内聚 低耦合 一个表只有一个主键 一个主键可以是多列 ‌第一范式&#xff08;1NF&#xff09;‌&#xff1a;要求数据库表的每一列都是不可分割的原子数据项&#xff0c;即列中存储的数据是最小的数据单元&…

并发服务器

一、服务器 1.单循环服务器&#xff1a;同一时刻&#xff0c;只能处理一个客户端的任务&#xff1b; 2.并发服务器&#xff1a;同一时刻&#xff0c;可以处理多个客户端的任务&#xff1b; 3.TCP并发服务器&#xff1a; &#xff08;1&#xff09;多进程: &#xff08;2&a…

搭建面向切面编程项目

此项目在整合Mybatis基础上修改&#xff0c;可参考主页的整合Mybatis文章 注解版本 第一步 引入maven坐标 <!-- 切面编程所需jar包--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId>…

Windows 11系统 Eclipse 2024版本安装教程和环境搭建

文章目录 目录 文章目录 安装流程 小结 概要安装流程技术细节小结 概要 Eclipse 是一个开源的集成开发环境 (IDE)&#xff0c;主要用于 Java 开发&#xff0c;但也支持其他编程语言如 C、Python 和 PHP。它提供了丰富的工具和插件&#xff0c;用于编写、调试和管理代码&#x…

安卓13 背光反向 亮度反向 android13 backlight reverse

总纲 android13 rom 开发总纲说明 目录 1.前言 2.问题分析 3.代码分析 4.代码修改 5.彩蛋 1.前言 有些设备,在调整背光的时候,会发现,背光调大,显示亮度反而变暗,背光调小,亮度变亮。这是由于PWM背光本身并没有一个标准去决定怎么样算是高亮度,怎么算是低亮度。因…

《黑神话·悟空》是用什么编程语言开发的?

最近火爆全球的国产 3A 大作《黑神话悟空》&#xff0c;你玩了吗&#xff1f;没玩没关系&#xff0c;有人就是对游戏不感冒&#xff0c;我找了个宣发片&#xff0c;一起感受下3A大作的视觉冲击&#xff0c;而且还是我们从小听到大&#xff0c;那猴子&#x1f412;的故事。 ‌‌…