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.mzph.cn/web/51481.shtml

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

相关文章

Adobe After Effects的插件--------CC Ball Action

CC Ball Action是粒子效果器,其将2D图层变为一个个由3D小球构成的图层。它是AE内置的3D插件。 使用条件 使用该插件的图层需是2D图层。 我们以一张图片素材为例: 给图片图层添加CC Ball Action效果控件,然后新建一个摄像机(利用摄像机旋转、平移、推拉工具,方便在各个角…

OpenCV几何图像变换(6)计算反转仿射变换函数invertAffineTransform()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 反转一个仿射变换。 该函数计算由 23 矩阵 M 表示的逆仿射变换&#xff1a; [ a 11 a 12 b 1 a 21 a 22 b 2 ] \begin{bmatrix} a_{11} & a…

OpenCV绘图函数(2)绘制圆形函数circle()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 绘制一个圆。 cv::circle 函数用于绘制一个给定中心和半径的简单圆或填充圆。 函数原型 void cv::circle (InputOutputArray img,Point cen…

【JVM】垃圾回收算法(一)

垃圾回收算法 Java程序在运行过程中会产生大量的对象&#xff0c;但是内存大小是有限的&#xff0c;如果光用而不释放&#xff0c;那内存迟早被耗尽。如C/C程序&#xff0c;需要程序员手动释放内存&#xff0c;Java则不需要&#xff0c;是由垃圾回收期去自动回收。垃圾回收器回…

基于x86 平台opencv的图像采集和seetaface6的眼睛状态检测(睁眼,闭眼)功能

目录 一、概述二、环境要求2.1 硬件环境2.2 软件环境三、开发流程3.1 编写测试3.2 配置资源文件3.3 验证功能一、概述 本文档是针对x86 平台opencv的图像采集和seetaface6的眼睛状态检测(睁眼,闭眼)功能,opencv通过摄像头采集视频图像,将采集的视频图像送给seetaface6的眼睛…

挑选适合的项目协同软件?看看这10款

文章主要介绍了以下10款项目协同进度软件&#xff1a;1.PingCode&#xff1b;2.Worktile&#xff1b;3.万户OA&#xff1b;4.小步外勤&#xff1b;5.智办事&#xff1b;6.万里牛&#xff1b;7.轻流&#xff1b;8.Toggl Track&#xff1b;9.Trello&#xff1b;10.Todoist。 在如…

PHP概述-特点-应用领域-如何学习

老师建议注册使用百度文心一言&#xff1b;讯飞星火大模型-AI大语言模型-星火大模型-科大讯飞&#xff1b;Kimi.ai - 帮你看更大的世界 等人工智能工具软件的一个到两个&#xff0c;也可下载文心一言、讯飞星火、kimi等APP软件使用&#xff0c;对于我们在读的大二学生来说有什么…

哪款麦克风音质效果好?一文看懂无线领夹麦克风什么品牌好

说到无线领夹麦克风麦克风&#xff0c;可能有些朋友对这个名字感觉很陌生&#xff0c;但是对于自媒体创作者以及短视频up主而言&#xff0c;应该会更熟悉一些。因为一款好的麦克风是提升音质的关键&#xff0c;而无线领夹麦克风作为一种小巧方便的收音设备&#xff0c;近些年更…

Citrix ADC Release 13.1 Build 54.29 (nCore, VPX, SDX, CPX, BLX) - 混合多云应用交付控制器

Citrix ADC Release 13.1 Build 54.29 (nCore, VPX, SDX, CPX, BLX) - 混合多云应用交付控制器 Citrix ADC - 混合多云应用交付控制器 请访问原文链接&#xff1a;https://sysin.org/blog/citrix-adc-13/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者…

spring boot(学习笔记第十九课)

spring boot(学习笔记第十九课) Spring boot的batch框架&#xff0c;以及Swagger3(OpenAPI)整合 学习内容&#xff1a; Spring boot的batch框架Spring boot的Swagger3&#xff08;OpenAPI&#xff09;整合 1. Spring boot batch框架 Spring Batch是什么 Spring Batch 是一个…

行为识别实战第二天——Yolov5+SlowFast+deepsort: Action Detection(PytorchVideo)

Yolov5SlowFastdeepsort 一、简介 YoloV5SlowFastDeepSort 是一个结合了目标检测、动作识别和目标跟踪技术的视频处理框架。这一集成系统利用了各自领域中的先进技术&#xff0c;为视频监控、体育分析、人机交互等应用提供了一种强大的解决方案。 1. 组件说明&#xff1a; Y…

51单片机最快能生成多高频率的方波?

前言 在嵌入式系统开发中&#xff0c;51 单片机作为一种非常非常非常经典&#xff0c;贯穿上下几十年的微控制器&#xff0c;被广泛应用于各种电子项目中。其中&#xff0c;生成特定频率的方波信号是一项常见的需求。 那么&#xff0c;51 单片机究竟能以多快的速度生成方波呢&…

26 colorchooser组件

Tkinter colorchooser 组件使用指南 Tkinter 的 colorchooser 组件提供了一个图形界面&#xff0c;用于选择颜色。它允许用户通过标准的颜色选择对话框来选择颜色&#xff0c;非常适合需要颜色选择功能的GUI应用程序。以下是对 colorchooser 组件的详细说明和一个使用案例。 …

UNI-APP 打包构建 APK

UNI-APP 打包构建 APK 前言一、WINDOWS&#xff08;在线 - 纯命令版&#xff09;依赖其他前置准备实现原理操作步骤 二、WINDOWS&#xff08;离线 - Android Studio 版&#xff09;依赖&#xff08;首次构建需要联网安装依赖&#xff09;其他前置准备实现原理操作步骤 三、WIND…

网络安全的历史

如今&#xff0c;网络安全几乎成为各大公司和利益相关者关注的焦点。但在早期&#xff0c;网络安全的概念非常模糊。 直到多年以后&#xff0c;由于网络攻击和危险实体威胁的频繁发生&#xff0c;网络安全的发展才受到重视。这些措施的发展成为了网络安全的演变。 网络安全起…

el-pagination 下拉条目数最后一个样式改成全部

2024.08.27今天我学习了如何把el-pagination的下拉条目数修改&#xff0c;效果如下&#xff1a; 我们需要把最后一条选择换成全部展示&#xff0c;其实传给后端的还是总的数量&#xff0c;只是换了一个content&#xff0c; 通过f12查看元素可以拿到.el-select-dropdown__item …

创建django项目时遇到的改项目名字问题

问题描述 今天在学习时遇到了一些问题&#xff0c;现记录一下。 今天我利用 ‘django-admin startproject 项目名字’命令创建了一个项目&#xff0c;并觉得当时项目名字没有命好&#xff0c;所以就随性的运行了 ’rename 旧项目名字 新项目名字‘这一命令。但是随后就出现…

使用idea快速创建springbootWeb项目(springboot+springWeb+mybatis-Plus)

idea快速创建springbootWeb项目 详细步骤如下 1&#xff09;创建项目 2&#xff09;选择springboot版本 3&#xff09;添加web依赖 4&#xff09;添加Thymeleaf 5&#xff09;添加lombok依赖 然后点击create进入下一步 双击pom.xml文件 6&#xff09;添加mybatis-plus依赖 …

C_03_函数学习

函数 优点&#xff1a; 降低代码耦合度降低代码冗余度提高代码复用率提高代码可读性 思想&#xff1a; 封装【包装】 声明&#xff1a; 语法&#xff1a; extern 函数名(形参列表)&#xff1b;// 注意&#xff1a;此时 形参列表中变量名可以忽略不写&#xff1b;定义&#xff1…

47.【C语言】指针(重难点)(J)

目录 26.自制排序函数(★★) *分析 *代码 往期推荐 26.自制排序函数 *分析 之前在42.【C语言】冒泡排序写过一个排序函数&#xff0c;可以将此自制一个类似qsort的函数 画圈的地方是需要修改的 #include <stddef.h> void bubble_sort(void* base, size_t num,size_t w…