Spring Security实战(五)—— 密码加密

news2024/11/16 3:29:14

一、密码加密的演进

MD5 (Message-Digest Algorithm 5) 和 SHA (Secure Hash Algorithm) 是两种常见的消息摘要算法,它们都被用于加密和数据完整性验证等领域。

MD5 是一种 128 位的哈希函数,常用于数据完整性校验和数字签名等方面。它将任意长度的信息映射为一个 128 位的摘要值,输出的值通常表示为一个 32 位的十六进制数。MD5 的安全性已经被破解,因此现在不再被广泛使用。

SHA 系列算法有多个版本,比较常见的有 SHA-1、SHA-256、SHA-384 和 SHA-512。它们都是将输入数据映射为一个固定长度的输出摘要值。SHA-1 生成的摘要长度为 160 位,而 SHA-256、SHA-384 和 SHA-512 分别生成 256 位、384 位和 512 位的摘要值。SHA-256 是目前应用最广泛的 SHA 算法之一,它的输出长度和安全性都比 MD5 更高。

Bcrypt 是一种密码哈希函数,可以用于对密码进行加密和验证。它是一种慢速哈希函数,其设计目的是为了防止暴力破解攻击和彩虹表攻击。Bcrypt 还可以通过增加 salt(随机值)和工作因子(算法运行次数)来进一步增强安全性。

Bcrypt 算法的实现中,会将明文密码和 salt 进行混合,并经过多轮哈希计算,最终得到一个长度为 60 个字符的密文。这个密文包括算法标识符、salt、工作因子和哈希值等信息。在验证密码时,Bcrypt 会从密文中提取出 salt 和工作因子,然后使用相同的哈希算法和参数来计算输入密码的哈希值,最后比较计算出的哈希值和密文中的哈希值是否一致。

由于 Bcrypt 算法的计算量比较大,因此它可以有效地防止暴力破解攻击和彩虹表攻击。同时,使用不同的 salt 和工作因子可以让相同的密码在不同的计算中生成不同的哈希值,进一步增加了破解难度。

因为其安全性较高,Bcrypt 已成为许多 Web 应用程序中默认的密码哈希函数,如 Ruby on Rails、Django 等。

Spring Security的密码加密机制

 Spring Security内置了密码加密机制,只需使用一个PasswordEncoder接口即可。

public interface PasswordEncoder {
    String encode(CharSequence rawPassword);

    boolean matches(CharSequence rawPassword, String encodedPassword);

    default boolean upgradeEncoding(String encodedPassword) {
        return false;
    }
}

这是一个密码编码器的 Java 接口定义,它规定了密码编码器需要实现的方法:

  • encode(CharSequence rawPassword) 方法用于对原始密码进行编码,返回编码后的密码字符串。
  • matches(CharSequence rawPassword, String encodedPassword) 方法用于检查原始密码和已编码密码是否匹配,返回匹配结果。这个方法在密码验证时被使用。
  • upgradeEncoding(String encodedPassword) 方法用于检查已编码密码是否需要升级加密,如果需要升级则返回 true,否则返回 false

该接口的具体实现可以使用不同的密码哈希算法,如 Bcrypt、SHA-256 等。使用密码编码器的主要目的是提高密码的安全性,将原始密码转化为不可逆的密文。在验证密码时,只需要比较原始密码经过编码后得到的密文和存储在数据库中的已编码密码是否匹配即可。

一些常用的实现类:

 (1)先对一个字符串进行加密

对密码 admin123 进行BCrypt加密,加密结果是:

$2a$10$cDqQrQ7OErpa78o8Wa8otekXnnwpGAOBHw5PXHaEjiNOB5ZJAsf9O

然后将数据库用户 admin 的密码修改为该密码:

(2)配置spring security

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());
    }

具体逻辑:

(1)提交用户名和密码之后,会将用户名和密码传给UsernamePasswordAuthenticationFilter

        UsernamePasswordAuthenticationFilter是Spring Security中一个非常重要的过滤器,它负责处理基于表单的身份验证,即当用户提交包含用户名和密码的表单时,该过滤器会从该请求中提取用户名和密码并进行身份验证。 

(2)UsernamePasswordAuthenticationFilter调用authenticate() 方法进行认证

        执行该方法时,它会获取请求中的用户名和密码参数,然后调用 AuthenticationManager 对象的 authenticate() 方法来进行身份验证。如果身份验证成功,则创建一个 Authentication 对象并将其传递给 SecurityContextHolder 中。如果身份验证失败,则会抛出 AuthenticationException。

 (3)AuthenticationManager 会继续调用DaoAuthenticationProvider的authenticate() 进行验证

        DaoAuthenticationProvider是一个AuthenticationProvider的实现类,用于处理用户名和密码验证的过程。当AuthenticationManager调用authenticate()方法时,实际上是委托给了DaoAuthenticationProvider来处理认证请求。

(4)DaoAuthenticationProvider也会调用 loadUserByUsername() 方法查询用户

        在DaoAuthenticationProvider的authenticate()方法中,会先调用UserDetailsService的loadUserByUsername()方法获取用户信息,(这里根据实际情况可能去内存中查找,也可以去数据库查找)然后再将获取到的用户信息与用户输入的密码进行比较,最终确定用户是否通过认证。因此,在认证流程中,loadUserByUsername()方法是一个非常重要的环节。

(5)返回 UserDetail对象

        loadUserByUsername() 方法主要是根据给定的用户名查询用户信息,并返回一个 UserDetails 对象。该方法的具体实现可能会涉及到访问数据库或其他存储设备,以获取用户的详细信息。在 Spring Security 中,这个方法通常由 UserDetailsService 的实现类来完成。在实现类中,通常会根据用户名查询用户信息,并将其封装为一个 UserDetails 对象,以便后续的身份验证过程中使用。UserDetails 对象包含用户的身份信息、授权信息和其他详细信息,如密码和是否启用等。

(6)通过PasswordEncoder对象对比UserDetail的密码和提交的密码是否一致

        通过PasswordEncoder对象将用户输入的密码加密,然后与UserDetails中存储的加密后的密码进行比较,来验证用户的身份。如果两者一致,则认为用户身份验证通过。PasswordEncoder主要用于将密码进行加密,以提高安全性。

(7)如果正确就把UserDetails中的权限信息设置到Authentication对象中

(8)返回Authentication对象

(9)将认证成功的 Authentication 对象存储在 SecurityContextHolder 中

(3)测试

 输入admin admin123 可以登陆成功

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

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

相关文章

WebServer项目(四)->(基于Proactor的c++)Web服务器简介及简单实现

基于Proactor的cWeb服务器项目 WebServer项目(四)->(基于Proactor的c)Web服务器简介及简单实现1.Web Server(网页服务器)2.HTTP协议(应用层的协议)3.HTTP 请求报文格式4.HTTP响应报文格式5.HTTP请求方法6.HTTP状态码7.服务器编程基本框架8.两…

分布式搜索技术elasticsearch概念篇

文章目录 一、分布式搜索技术二、elasticsearch2.1 初识elasticsearch2.2 正向索引和倒排索引2.2.1 介绍2.2.2 优缺点 2.3 elasticsearch和mysql的对比 一、分布式搜索技术 分布式搜索技术是一种基于分布式计算的搜索引擎技术,它使用多台计算机协同工作来处理大规模…

ElementUI登陆表单中常用的标签属性

ElementUI官网 为登陆框添加一个边角弧度 <style> .className{/*设置div边边框角的弧度*/border-radius: 10px; } </style><el–input>标签常用属性 <!--使用prefix属性添加一个前缀图标--> <el-input prefix-icon"el-icon-user-solid"&g…

深度学习第J6周:ResNeXt-50实战解析

目录 一、模型结构介绍 二、前期准备 三、模型 三、训练运行 3.1训练 3.2指定图片进行预测 &#x1f368; 本文为[&#x1f517;365天深度学习训练营]内部限免文章&#xff08;版权归 *K同学啊* 所有&#xff09; &#x1f356; 作者&#xff1a;[K同学啊] &#x1f4cc; …

大数据技术之集群数据迁移

在大数据集群数据迁移的项目中涉及到很多技术细节&#xff0c;本博客记录了迁移的大致的操作步骤。 迁移借用Hadoop自带的插件&#xff1a;distcp。 一、Hadoop集群数据迁移 **DistCp&#xff08;分布式拷贝&#xff09;**是用于大规模集群内部和集群之间拷贝的工具。它使用M…

Meson构建系统的使用

一、前言 Meson 是用于自动化构建的自由软件&#xff0c;使用Python语言编写&#xff0c;在 Apache 许可证 2.0版本下发布&#xff0c;主要目标是为了让开发者节约用于配置构建系统的时间。 特点如下&#xff1a; 多平台支持&#xff0c;包括 GNU/Linux、Windows、MacOS、GCC、…

A_A01_008 STM32F103系列标准库移植经验分享

A_A01_008 STM32F103系列标准库移植经验分享 一、所需材料二、移植步骤三、注意事项四、参考资料与友情链接 一、所需材料 1.MDK开发环境 此处版本V5.15 2.相关启动文件 此处用野火点灯例程 因为启动文件完整 方便更换 其它工程没有的可以直接复制这些启动文件过去 3.相关开…

Java版工程管理系统源代码-软件自主研发,工程行业适用

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示…

8年测开年薪30W,为什么从开发转型为测试?谈谈这些年的心路历程……

谈谈我的以前&#xff0c;从毕业以来从事过两个多月的Oracle开发后转型为软件测试&#xff0c;到现在已近过去8年成长为一个测试开发工程师&#xff0c;总结一下之间的心路历程&#xff0c;希望能给徘徊在开发和测试之前的同学一点小小参考。 一、测试之路伏笔 上学偷懒&#…

EGO-Link FPGA智慧教育社区介绍:用 leetcode 的方式练习 verilog 语言

文章目录 介绍FPGA 语法例1&#xff1a;P1203 1输入1输出例2&#xff1a;P1204 3输入4输出例3&#xff1a;P1207 P1208 P1205 与或非门例4&#xff1a;P1200 半加器例5&#xff1a;P1201 4位二进制转余3循环码例6&#xff1a;P1215 2选1多路选择器例7&#xff1a;P1236 D触发器…

【C语言】浅涉结构体(声明、定义、类型、定义及初始化、成员访问及传参)

简单不先于复杂&#xff0c;而是在复杂之后。 目录 1. 结构体的声明 1.1 结构体的基础知识 1.2 结构的声明 1.3 结构成员的类型 1.4 结构体变量的定义和初始化 2. 结构体成员的访问 3. 结构体传参 1. 结构体的声明 1.1 结构体的基础知识 结构是一些值的集合&…

探索Apache Hudi核心概念 (4) - Clustering

Clustering是Hudi在0.7.0版本引入的一项特性&#xff0c;用于优化文件布局&#xff0c;提升读写性能&#xff0c;现在它已经成为Hudi的一项重要性能优化手段。本文我们会通过Notebook介绍并演示Clustering的运行机制&#xff0c;帮助您理解其工作原理和相关配置。 1. 运行 Not…

RocketMQ 多级存储设计与实现

作者&#xff1a;张森泽 随着 RocketMQ 5.1.0 的正式发布&#xff0c;多级存储作为 RocketMQ 一个新的独立模块到达了 Technical Preview 里程碑&#xff1a;允许用户将消息从本地磁盘卸载到其他更便宜的存储介质&#xff0c;可以用较低的成本延长消息保留时间。本文详细介绍 …

记录贴:EasyPoi word导出问题一览

项目场景&#xff1a; EasyPoi word导出 问题描述1 easypoi 模板导出 我直接在map的value输入空格或"",出来的是{{,两个左花括号,咋解决 解决方案&#xff1a; exportMap.put("key", "\u00A0"); //空格前端效果&#xff1a; 其他无效解决方案…

Redis安装配置操作记录

Redis 官网&#xff1a;https://redis.io/ 中文文档&#xff1a;https://www.redis.com.cn/documentation.html 在线命令参考&#xff1a;http://doc.redisfans.com 一&#xff0c;Redis下载安装与配置 下载网站&#xff0c;可下载安装包然后安装或可使用brew来安装Redis&#…

LeetCode——前K个高频单词

692. 前K个高频单词 给定一个单词列表 words 和一个整数 k &#xff0c;返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率&#xff0c; 按字典顺序 排序。 示例 1&#xff1a; 输入: words [“i”, “love”, “le…

太阳能电池测试解决方案NS-9001

前言 太阳能行业的快速发展提高了对太阳能电池测试和精确测量解决方案要求&#xff0c;伴随着太阳能电池尺寸大小质量的提升&#xff0c;充电电池测试必须更多的电流和更高输出功率水准&#xff0c;这就更加需要灵活多变的测试方案支持。 现阶段&#xff0c;太阳能电池测试 解…

Java学习星球,Java学习路线

目录 一、Java学习路线二、学习计划三、为何会有Java学习星球&#xff1f;四、加入星球后&#xff0c;你可以得到什么&#xff1f;五、如何加入Java学习星球&#xff1f;六、打卡挑战 大家好&#xff0c;我是哪吒&#xff0c;一个靠着热情攀登至C站巅峰的中年男子&#xff0c;C…

【历史上的今天】3 月 20 日:cURL 二十五周年;Docker 发布;思科收购 Linksys

整理 | 王启隆 透过「历史上的今天」&#xff0c;从过去看未来&#xff0c;从现在亦可以改变未来。 今天是 2023 年 3 月 20 日&#xff0c;在 1999 年的今天&#xff0c;人类首次成功乘热气球环球飞行。在 24 年的今天&#xff0c;瑞士人皮尔卡、英国人琼斯经过近 20 天的飞行…

JavaWeb—HTTP协议

目录 1.HTTP协议 1.1 HTTP-概述 1.1.1 介绍 2.1.2 特点 1.2 HTTP-请求协议 HTTP-请求数据格式 GET请求和POST请求的区别&#xff1a; 1.3 HTTP-响应协议 1.3.1 格式介绍 1.3.2 响应状态码 常见响应状态码 1.4 HTTP-协议解析 1.HTTP协议 1.1 HTTP-概述 1.1.1 介绍 HTT…