非对称加密 RS256 / 对称加密 HS256 的区别,以及 JWT「失效」到底是怎么判断的?
在使用 JWT(JSON Web Token)进行身份认证时,RS256 / HS256 以及 Token 过期与失效机制 是两个绕不开的核心问题。
很多同学在实践中会产生这样的困惑:
- 验签到底在验什么?
- exp 过期是怎么判断的?
- 验签通过了,为什么 Token 还是无效?
- RS256 和 HS256 只是“算法不同”吗?
本文将从 原理 → 实现 → 安全 → 实战设计 的角度,系统性地把这两个问题讲清楚。
一、JWT 的基本结构回顾
一个标准的 JWT 由三部分组成:
header.payload.signature
——————————
eyJhbGciOiJ9.eyJzdWIiOjM5MDIyfQ.SflKxwRJJf36POssw5c
- Header:声明使用的算法(如 RS256 / HS256)
- Payload:业务数据(用户信息、过期时间等)
- Signature:防篡改签名(安全核心)
其中:
- Header 和 Payload 只是 Base64 编码,可被解码查看
- Signature 才是用来防止伪造和篡改的关键
二、HS256 与 RS256 的核心区别
1. HS256:对称加密(HMAC + SHA-256)
原理
signature = HMAC_SHA256(
header.payload,
secretKey
)
- 使用 同一个密钥
- 既负责 签名,也负责 验签
特点
- 实现简单
- 性能高
- 适合单体应用或内部系统
安全隐患(重点)
任何拿到 secretKey 的服务,都可以伪造 Token
在微服务或第三方校验场景中,这是不可接受的。
2. RS256:非对称加密(RSA + SHA-256)
原理
私钥(Private Key) → 签名
公钥(Public Key) → 验签
signature = RSA_SHA256(
header.payload,
privateKey
)
特点
- 私钥只存在于认证中心
- 公钥可下发给所有资源服务
- 验签方无法伪造 Token
为什么更安全?
即使公钥泄露,也无法反推出私钥
因此:
- OAuth2
- 单点登录
- 微服务架构
几乎全部使用 RS256。
3. HS256 vs RS256 对比总结
| 密钥类型 | 对称密钥 | 非对称密钥 |
| 密钥数量 | 1 个 | 2 个(公钥 / 私钥) |
| 是否适合微服务 | ❌ | ✅ |
| 是否支持安全密钥轮换 | 困难 | 容易 |
| 安全边界 | 较弱 | 强 |
| 性能 | 更快 | 稍慢 |
三、JWT 验签流程到底在做什么?
很多人会把「验签」和「是否有效」混为一谈,其实这是两个完全不同的阶段。
验签做的事情只有一件:
1. 取出 header.payload
2. 使用约定的算法 + 服务端密钥
3. 重新计算 signature'
4. 与 token 中的 signature 对比
结果只有两种:
- ❌ 不一致 → Token 被篡改(直接无效)
- ✅ 一致 → 只能说明 Token 是“真的”
⚠️ 注意:
验签通过 ≠ Token 还能用
四、Token 的「失效」是怎么判断的?
关键结论
JWT 的失效不是“算出来的”,而是“读出来的”
失效信息在 Payload 里。
五、最核心的失效字段:exp
1. exp 是什么?
{
"sub": "10086",
"iat": 1700000000,
"exp": 1700003600
}
- exp:expiration time(过期时间,秒级时间戳)
2. 判断逻辑
if (now > exp) {
token 已过期
}
重要认知
- exp 不影响签名是否正确
- 它只是 payload 中的一个字段
- 所以会出现:
| 签名正确 + exp 未过期 | Token 有效 |
| 签名正确 + exp 已过期 | Token 失效 |
| 签名错误 | Token 无效 |
六、完整的 Token 有效性判断流程(生产级)
真实系统中,一个请求的 JWT 校验流程是:
1️⃣ 校验签名(防伪)
2️⃣ 解析 payload
3️⃣ 校验 exp(是否过期)
4️⃣ 校验 nbf / iat(可选)
5️⃣ 业务层校验(是否被吊销、版本是否匹配)
只要 任意一步失败:
→ SecurityContext 不会建立
→ 返回 401 / 403
七、除了 exp,还有哪些失效手段?
1. nbf(Not Before)
"nbf": 1700001000
含义:
在该时间之前,Token 不允许被使用
2. 服务端主动让 Token 失效(非常常见)
JWT 是无状态的,但业务不是。
常见方案:
方案一:Token 黑名单(Redis)
- 登出 / 封禁
- 把 token / jti 存入 Redis
- 每次请求校验
方案二:用户版本号
{
"uid": 1,
"ver": 3
}
- 数据库中版本是 4
- Token 中是 3
- 判定失效
八、Access Token + Refresh Token 的设计
推荐实践:
Access Token:15 分钟
Refresh Token:7 天
- Access Token 过期 → 走刷新流程
- Refresh Token 过期 → 重新登录
这也是 JWT 能做到“无状态 + 可控失效”的关键。
九、和 Spring Security 的整体执行链路
在 Spring Security 中,真实流程是:
请求进入
→ JWT Filter
→ 校验签名
→ 校验 exp
→ 校验业务状态
→ 构造 Authentication
→ 放入 SecurityContext
→ @AuthenticationPrincipal 生效
十、总结一句话记住
🔐 签名解决的是「有没有被伪造」
⏰ exp 解决的是「现在还能不能用」
🧠 业务校验解决的是「我还认不认你」
结语
- HS256:适合简单、封闭系统
- RS256:生产环境首选,安全边界清晰
- JWT 有效 ≠ 验签通过
网硕互联帮助中心







评论前必须登录!
注册