BCrypt 与 JWT 认证流程学习笔记

一、先记住区别

  • BCrypt:保护用户密码,负责注册时保存密码哈希、登录时核对密码。
  • JWT:登录成功后发给用户的身份令牌,后续访问接口时用于认证和权限检查。
  • 哈希不等于加密:BCrypt 是单向密码哈希,不能解密还原密码。
  • JWT 不等于加密 :本项目使用的是 HS256 签名 JWT,内容可被解码查看,但不能在不知道密钥的情况下有效篡改。

二、BCrypt:注册和登录

1. 注册流程

text 复制代码
用户输入密码 123456
        ↓
BCrypt.encode("123456")
        ↓
自动生成随机盐 Salt,并进行密码哈希计算
        ↓
数据库保存 BCrypt 哈希字符串(包含算法版本、成本参数、盐、哈希结果)

为什么加盐? 即使两个人的密码相同,随机盐不同,生成的哈希通常也不同。

2. 登录流程

text 复制代码
用户输入密码 123456
        ↓
从数据库读取已保存的 BCrypt 哈希
        ↓
BCrypt.matches(输入密码, 数据库哈希)
        ↓
取出哈希中记录的盐和成本参数,重新计算并比较
        ↓
相同 → 登录密码正确;不同 → 密码错误

重点 :matches() 不会解密数据库密码,也不会另生成一个随机盐;它使用旧哈希里存储的盐重新计算。

java 复制代码
// 注册:保存哈希,而不是明文密码
String hash = passwordEncoder.encode("123456");

// 登录:验证用户输入的密码
boolean correct = passwordEncoder.matches("123456", hash);

其中 PasswordEncoder 是接口,BCryptPasswordEncoder 是实现类,passwordEncoder 只是变量名。

三、JWT:登录后生成令牌、访问时验证

1. 生成 JWT

text 复制代码
用户登录,BCrypt 验证密码正确
        ↓
JwtEncoder 使用服务器 SecretKey 签名
        ↓
生成 JWT,返回给客户端

JWT 由三个部分组成:

text 复制代码
Header.Payload.Signature
  • Header(头部) :声明签名算法,例如 HS256。
  • Payload(载荷) :保存用户 ID、角色 roles、过期时间 exp 等信息;可以被解码查看,不要放密码。
  • Signature(签名):服务器使用SecretKey密钥,对前两部分计算出的防篡改校验值。

2. 访问接口

text 复制代码
客户端发送请求
Authorization: Bearer <JWT>
        ↓
Spring Security 自动获取 Token
        ↓
JwtDecoder 用服务器密钥验证签名、检查有效期
        ↓
读取用户角色,检查接口权限
        ↓
通过 → 进入 Controller;失败 → 拒绝请求
  • 401 Unauthorized:未提供有效身份凭证,例如没有 Token、Token 过期或签名错误。
  • 403 Forbidden :身份已验证,但权限不够,例如 USER 访问管理员接口。

3. 为什么修改角色会导致签名失效?

text 复制代码
原来:Payload 里 roles = USER  → 服务器生成签名 A
篡改:Payload 里 roles = ADMIN → 应该生成签名 B

签名取决于 Header + Payload + SecretKey。修改 Payload 后,旧签名 A 与服务器重新计算的签名不一致,就会被拒绝。攻击者没有服务器的密钥,无法生成正确的新签名。

四、常见专有名词

名词 通俗解释
BCrypt 专门保护密码的单向哈希算法,计算较慢,能增加暴力猜密码的成本。
Hash(哈希) 把数据计算成固定格式的摘要,通常不能反向还原原数据。
Salt(盐) 每次创建密码哈希时生成的随机值;不需要保密,防止相同密码总得到相同哈希。
PasswordEncoder Spring Security 提供的密码编码与校验接口。
JWT JSON Web Token,保存身份声明和签名的令牌格式。
Token 客户端携带的身份凭证。
HS256 JWT 中的算法名称,表示使用 HMAC-SHA256 计算签名。
HMAC-SHA256 利用密钥 + 数据生成签名校验值的算法;没有正确密钥就难以伪造有效签名。
SecretKey 服务器保管的 JWT 签名密钥;与 BCrypt 的随机盐无关。
JwtEncoder 生成并签名 JWT;通常由登录业务代码主动调用。
JwtDecoder 解析并验证 JWT;Spring Security 可在请求认证时自动调用。
Bearer HTTP Authorization 请求头中携带 Token 的方式。
Claim JWT Payload 中的一项数据,例如 sub、roles、exp。

五、一句话串起完整流程

注册时 BCrypt 生成密码哈希并存库 → 登录时 BCrypt 使用旧盐验证密码 → 成功后 JwtEncoder 用 SecretKey 签发 JWT → 请求携带 Bearer Token → Spring Security 调用 JwtDecoder 验证 JWT → 按角色决定能否访问接口。

记忆口诀:BCrypt 管密码;JWT 管登录后的身份;Salt 用于密码哈希,SecretKey 用于 JWT 签名。

相关推荐
问心无愧05131 小时前
[极客大挑战 2019]HardSQL
笔记
apple_692658851 小时前
QX 效率启动器安装包:开源生产力工具,快捷键统一入口Raycast免费开源平替版来啦
学习·开源·办公
一直C1 小时前
嵌入式 Linux 驱动开发学习笔记:中断、等待队列与工作队列
linux·驱动开发·嵌入式硬件·学习·imx6ull
问心无愧05131 小时前
[GXYCTF2019]BabyUpload
笔记
我命由我123451 小时前
5-2.Python 编码进阶 - 字符串进阶(拼接、普通格式化、普通格式化数字精度控制、快速格式化、遍历、常用方法)
java·开发语言·后端·python·学习·java-ee·学习方法
http阿拉丁神猫6 小时前
Go语言入门笔记:从基础到开发环境搭建(二)
开发语言·笔记·golang
HRBorderInsight9 小时前
马来西亚人均收入一个月多少钱,个人薪资和家庭收入要分开看
经验分享·笔记
又見山10 小时前
本地 Markdown 与数据主权:你的笔记到底属于谁
笔记·obsidian
撩得Android一次心动12 小时前
Jetpack Compose 知识点整理2【个人用】
android·笔记·学习·kotlin·compose