一、使用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的更多相关文章

  1. 浅谈使用spring security中的BCryptPasswordEncoder方法对密码进行加密与密码匹配

    浅谈使用springsecurity中的BCryptPasswordEncoder方法对密码进行加密(encode)与密码匹配(matches) spring security中的BCryptPass ...

  2. 使用 spring security 中的BcryptPasswordEncoder对象对用户密码进行加密

    一.引入security启动器 在子工程中直接引入,不用指定版本号 二.在启动类中把BCryptPasswordEncoder对象注入到容器中 三.在service 层注入 四. 调用encode方法 ...

  3. Spring Security 中的 Bcrypt

    最近在写用户管理相关的微服务,其中比较重要的问题是如何保存用户的密码,加盐哈希是一种常见的做法.知乎上有个问题大家可以先读一下: 加盐密码保存的最通用方法是? 对于每个用户的密码,都应该使用独一无二的 ...

  4. [收藏]Spring Security中的ACL

    ACL即访问控制列表(Access Controller List),它是用来做细粒度权限控制所用的一种权限模型.对ACL最简单的描述就是两个业务员,每个人只能查看操作自己签的合同,而不能看到对方的合 ...

  5. Spring Security中html页面设置hasRole无效的问题

    Spring Security中html页面设置hasRole无效的问题 一.前言 学了几天的spring Security,偶然发现的hasRole和hasAnyAuthority的区别.当然,可能 ...

  6. Spring Security 中的过滤器

    本文基于 spring-security-core-5.1.1 和 tomcat-embed-core-9.0.12. Spring Security 的本质是一个过滤器链(filter chain) ...

  7. 看源码,重新审视Spring Security中的角色(roles)是怎么回事

    在网上看见不少的博客.技术文章,发现大家对于Spring Security中的角色(roles)存在较大的误解,最大的误解就是没有搞清楚其中角色和权限的差别(好多人在学习Spring Security ...

  8. 六:Spring Security 中使用 JWT

    Spring Security 中使用 JWT 1.无状态登录 1.1 什么是有状态? 1.2 什么是无状态 1.3 如何实现无状态 2.JWT 2.1 JWT数据格式 2.2 JWT交互流程 2.3 ...

  9. 五:Spring Security 中的角色继承问题

    Spring Security 中的角色继承问题 以前的写法 现在的写法 源码分析 SpringSecurity 在角色继承上有两种不同的写法,在 Spring Boot2.0.8(对应 Spring ...

  10. Spring Security中实现微信网页授权

    微信公众号提供了微信支付.微信优惠券.微信H5红包.微信红包封面等等促销工具来帮助我们的应用拉新保活.但是这些福利要想正确地发放到用户的手里就必须拿到用户特定的(微信应用)微信标识openid甚至是用 ...

随机推荐

  1. C#开源免费的Windows右键菜单管理工具

    前言 今天分享一个C#开源.免费.纯粹的Windows右键菜单管理工具:ContextMenuManager. 工具主要功能 程序支持国际化多语言显示. 启用或禁用文件.文件夹.新建.发送到.打开方式 ...

  2. 51单片机封装库HML_FwLib_STC89/STC11

    HML_FwLib_STC89/11 项目地址 https://github.com/MCU-ZHISHAN-IoT/HML_FwLib_STC89 https://github.com/MCU-ZH ...

  3. 【Unity3D】Renderer Feature简介

    1 3D 项目迁移到 URP 项目后出现的问题 ​ 3D 项目迁移至 URP 项目后,会出现很多渲染问题,如:材质显示异常.GL 渲染不显示.多 Pass 渲染异常.屏幕后处理异常等问题.下面将针对这 ...

  4. jupyter环境变量配置与启动

    一.jupyter基础知识 1.基本概念 jupyter是基于网页的用于交互计算的应用程序.其可被应用于全过程计算:开发.文档编写.运行代码和展示结果. 编程时具有语法高亮,缩进,tab补全的功能. ...

  5. sentry 在加载模块时闪退

    这是一个很久之前的问题了,今天记录一下,以便遇到同样问题的同学能够看到此文章 崩溃环境: 目前仅收到 windows 7 的部分用户反馈,在程序启动时发生闪退 问题分析: 查看用户提供的日志,可以看见 ...

  6. celery中异步延迟执行任务apply_anysc的用法

    描述 首先说下异步任务执行delay()和apply_anysc()两者区别,其实两者都是执行异步任务的方法,delay是apply_anysc的简写.所以delay中传递的参数会比apply_any ...

  7. Ubuntu18.04搭建Vue开发环境

    更新软件源列表 sudo apt update nodejs安装 sudo apt install nodejs nodejs -v #查看版本 npm安装 sudo apt install npm ...

  8. 【WiFi开发全攻略】WIFI基础知识大全

    [WiFi开发全攻略]WIFI基础知识大全 1. Wi-Fi起源 现在我们大家对Wi-Fi肯定都不陌生,无论是笔记本,手机,智能电视,都离不开Wi-Fi.目前我们一般用的都是Wi-Fi5,Wi-Fi6 ...

  9. 自然周算法-javascript实现

    获取自然周 js获取自然周 本文作者:bigroc 本文链接:https://www.cnblogs.com/bigroc/p/14888550.html 代码 function getWeeks() ...

  10. 第134篇:解决浏览器的CORS跨域问题(CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome-untrusted, https, edge.)

    好家伙,   我继续尝试着将我的飞机大战使用ES6模块化分离开来,出了点问题 1.出现问题: edge,chrome等一系列浏览器,会为了安全,禁止你跨域访问 目录如下: 主程序  index.htm ...