Spring Security 中的 BCryptPasswordEncoder
一、使用BCryptPasswordEncoder加密的值可以解出来吗
Spring Security 中的 BCryptPasswordEncoder 是一种单向加密算法,它是为了安全性考虑而设计的,因此无法从加密后的密码值"解密"出原始密码。这是出于安全目的的设计。
BCryptPasswordEncoder 加密过程是不可逆的,即使你有加密后的密码值,也无法通过任何方式获得原始密码。这种单向加密的目的就是为了防止密码泄露后被破解。
通常,在实际应用中,我们只需要将用户输入的原始密码使用 BCryptPasswordEncoder 进行加密,然后将加密后的密码值存储在数据库中。在用户登录时,将用户输入的密码加密后,与存储在数据库中的加密密码进行比对,如果相同则验证通过,而无需知道原始密码。
因此,你无法从 BCryptPasswordEncoder 加密后的密码值中"解密"出原始密码。这正是它被设计用于密码加密的目的,以提高系统的安全性。如果你需要知道用户的原始密码,建议在注册时不对密码进行加密,或者提供"忘记密码"的功能让用户重置密码。
二、为什么每次BCryptPasswordEncoder加密的值不一样,却可以都匹配上原始密码
这是因为 BCryptPasswordEncoder 在加密时会自动添加一个随机的 Salt 值,这个 Salt 值的作用是使得相同的原始密码在每次加密时产生不同的密文,从而增加密码的安全性。
具体来说,BCryptPasswordEncoder 加密过程包括以下几个步骤:
1. 生成一个随机的 Salt 值,通常是 16 字节长度。
2. 将原始密码和 Salt 值进行合并。
3. 对合并后的值进行 BCrypt 哈希运算,计算出最终的密文。
4. 将 Salt 值和密文拼接在一起,作为最终的加密结果。
因此,每次加密相同的原始密码时,由于使用了不同的随机 Salt 值,所以最终的加密结果也是不同的。
在验证密码时,BCryptPasswordEncoder 会自动从加密结果中提取出 Salt 值,并使用相同的方式对输入的原始密码进行加密,然后比较两个密文是否相同。由于使用了相同的 Salt 值,所以即使每次加密后的结果不同,只要原始密码相同,通过 BCrypt 算法计算出的密文就是相同的。
这种机制不仅增加了密码的安全性,而且还能防止采用相同密码的不同用户的密文相同,从而增加了"彩虹表"攻击的难度。所以即使每次加密结果不同,BCryptPasswordEncoder 依然能够正确比对密码。
三、BCryptPasswordEncoder 加密结果的格式
在 BCryptPasswordEncoder 加密后的结果中,前 29 个字符是包含了 Salt 值和其他算法信息的部分,后面的字符串才是实际的密文部分。
具体来说,BCryptPasswordEncoder 加密结果的格式是:
```
$算法标识$rounds$salt$密文
```
其中:
- `$算法标识` 是一个固定的字符串 `$2a$`、`$2b$` 或 `$2y$`等,用于标识使用的哈希算法版本。
- `$rounds` 是一个十进制数字,表示算法迭代的次数。
- `$salt` 是一个 22 个字符长的 Base64 编码的字符串,这就是加密时使用的随机 Salt 值。
- `$密文` 是实际的密文部分,长度为 31 个字符。
例如,一个典型的 BCryptPasswordEncoder 加密结果可能是:
```
$2a$10$N9qo8uHh24cuh6zT6ZsEfe6Fzen7kNSNBqh.FkQPvQUNhxfrasXTi
```
在这个加密结果中:
- `$2a$` 表示使用 BCrypt 算法的版本 2a
- `10` 表示迭代次数为 10
- `N9qo8uHh24cuh6zT6ZsEfe` 就是 22 个字符长的随机 Salt 值
- 最后 31 个字符 `6Fzen7kNSNBqh.FkQPvQUNhxfrasXTi` 才是实际的密文部分
所以,BCryptPasswordEncoder 加密结果中,第 4 到第 25 个字符就是随机生成的 Salt 值。每次加密相同的密码,这部分 Salt 值都会不同,从而导致最终的加密结果也不相同。但在验证时,会自动提取出这个 Salt 值用于计算,所以能够正确比对密码。
四、Salt 值和真实密码合并后的值进行 BCrypt 哈希运算,如果知道salt值和最终的密文可以解出原来的密码吗
即使知道了Salt值和最终的密文,也无法通过任何方式反解出原始的密码。
这是因为BCrypt是一种经过加盐(Salting)的单向自适应密钥导出函数(Key Derivation Function),它的设计目的就是使得从密文反推原始密码是计算上不可行的。
具体来说,BCrypt算法包含以下几个关键设计:
1. 使用了Eksblowfish算法作为核心,这是一种密钥设置可变的块加密算法,具有良好的密码学性质。
2. 在密钥设置中引入了可变的迭代次数,默认为2^10次,这使得暴力破解的计算代价大大增加。
3. 在密钥设置中引入了随机的Salt值,使得相同的密码每次产生的密文都不同,防止彩虹表攻击。
4. 密钥设置过程是自适应和可变的,可以根据硬件性能动态调整计算代价。
5. 最终密文使用Base64编码,长度为53个字符,其中包含了Salt和其他算法参数。
因此,即使已知Salt值和密文,要反解出原始密码,仍然需要进行大量的计算和暴力破解。由于BCrypt算法设计的目的就是使这种破解行为在计算上不可行,所以实际上是无法通过任何方式从Salt和密文中反解出原始密码的。
这就是BCrypt作为密码哈希算法的设计理念和安全保证。除非原始密码非常简单且Salt和迭代次数设置较低,否则从BCrypt密文中反解是极其困难的。
Spring Security 中的 BCryptPasswordEncoder的更多相关文章
- 浅谈使用spring security中的BCryptPasswordEncoder方法对密码进行加密与密码匹配
浅谈使用springsecurity中的BCryptPasswordEncoder方法对密码进行加密(encode)与密码匹配(matches) spring security中的BCryptPass ...
- 使用 spring security 中的BcryptPasswordEncoder对象对用户密码进行加密
一.引入security启动器 在子工程中直接引入,不用指定版本号 二.在启动类中把BCryptPasswordEncoder对象注入到容器中 三.在service 层注入 四. 调用encode方法 ...
- Spring Security 中的 Bcrypt
最近在写用户管理相关的微服务,其中比较重要的问题是如何保存用户的密码,加盐哈希是一种常见的做法.知乎上有个问题大家可以先读一下: 加盐密码保存的最通用方法是? 对于每个用户的密码,都应该使用独一无二的 ...
- [收藏]Spring Security中的ACL
ACL即访问控制列表(Access Controller List),它是用来做细粒度权限控制所用的一种权限模型.对ACL最简单的描述就是两个业务员,每个人只能查看操作自己签的合同,而不能看到对方的合 ...
- Spring Security中html页面设置hasRole无效的问题
Spring Security中html页面设置hasRole无效的问题 一.前言 学了几天的spring Security,偶然发现的hasRole和hasAnyAuthority的区别.当然,可能 ...
- Spring Security 中的过滤器
本文基于 spring-security-core-5.1.1 和 tomcat-embed-core-9.0.12. Spring Security 的本质是一个过滤器链(filter chain) ...
- 看源码,重新审视Spring Security中的角色(roles)是怎么回事
在网上看见不少的博客.技术文章,发现大家对于Spring Security中的角色(roles)存在较大的误解,最大的误解就是没有搞清楚其中角色和权限的差别(好多人在学习Spring Security ...
- 六:Spring Security 中使用 JWT
Spring Security 中使用 JWT 1.无状态登录 1.1 什么是有状态? 1.2 什么是无状态 1.3 如何实现无状态 2.JWT 2.1 JWT数据格式 2.2 JWT交互流程 2.3 ...
- 五:Spring Security 中的角色继承问题
Spring Security 中的角色继承问题 以前的写法 现在的写法 源码分析 SpringSecurity 在角色继承上有两种不同的写法,在 Spring Boot2.0.8(对应 Spring ...
- Spring Security中实现微信网页授权
微信公众号提供了微信支付.微信优惠券.微信H5红包.微信红包封面等等促销工具来帮助我们的应用拉新保活.但是这些福利要想正确地发放到用户的手里就必须拿到用户特定的(微信应用)微信标识openid甚至是用 ...
随机推荐
- NC19777 卡牌游戏
题目链接 题目 题目描述 小贝喜欢玩卡牌游戏.某个游戏体系中共有N种卡牌,其中M种是稀有的.小贝每次和电脑对决获胜之后都会有一个抽卡机会,这时系统会随机从N种卡中选择一张给小贝.普通卡可能多次出现,而 ...
- PC端应用程序自动化测试——pywinauto、pywin32、pyautogui
1 前言 PC 端自动化测试使用到的 python 模块主要有 pywinauto.win32gui.pyautogui,主要功能如下: pywinauto:主要使用到 Application 类,用 ...
- cdn缓存立刻刷新
现在例如有一个业务需求是客户更新图片,那我们需要及时更新,可是正常的上传是无法及时更新的,因为七牛云会有客户端缓存和cdn缓存,这时候可能有多种处理方式: 1.cdn和客户端缓存的时间调短,例如1 ...
- 解决VMware与win10无法共享目录
1.安装VMware Tools 这一步适用于多数情况,但对于高版本的VMWare这一步无效,当然了,先试一试总没有坏处. 有看见网上说如果VMware内安装的是高版本的Ubuntu,安装的VMwar ...
- Redis原理再学习03:数据结构-链表 list
链表list介绍 1. 链表list简介 链表(linked list)是一种基础数据结构,是一种线性表,但是不会按照线性表的顺序存储数据,而是在每一个节点里存到下一个节点的指针. 链表插入节点时是 ...
- r0tracer 源码分析
使用方法 修改r0tracer.js文件最底部处的代码,开启某一个Hook模式. function main() { Java.perform(function () { console.Purple ...
- h5页面在微信打开,ios底部存在返回横条的问题
我的问题比较简单,一个处理链接的页面,二次跳转进入真正的页面,导致ios出现返回横条,点击后退回到了处理链接页面.因为这个后退不会重新加载,导致一直处在处理链接的这个空页面. 所以我用replace代 ...
- 最简单的python判断是否是回文
def isNumberPalindrome(number): if isinstance(number, int): number = str(number) return number == nu ...
- 【Azure 云服务】Azure Cloud Service中的错误事件 Error Event(Defrag/Perflib) 解答
问题描述 在Azure Cloud Service的实例中,收集到各种 Error Event 内容,本文针对所收集的三种Event进行解析. 1: This operation is not sup ...
- [C++] epoll编写的echo服务端
直接贴代码,代码是运行在Linux上面的,通过 g++ epoll.cpp编译 #include <sys/socket.h> #include <sys/epoll.h> # ...