深入了解Json Web Token之概念篇
字数 3412 2025-08-18 11:37:33
JSON Web Token (JWT) 全面解析
1. JWT 概述
JSON Web Token (JWT) 是一种开放标准 (RFC 7519),用于在各方之间安全地传输信息作为 JSON 对象。JWT 的主要目的是在服务端和客户端之间以安全的方式来转移声明。
1.1 JWT 的主要应用场景
- 认证 (Authentication)
- 授权 (Authorization)
- 联合识别
- 客户端会话(无状态的会话)
- 客户端机密
1.2 JWT 相关术语
- JWS (Signed JWT): 签名过的 JWT
- JWE (Encrypted JWT): 部分 payload 经过加密的 JWT
- JWK (JWT Key): JWT 的密钥(secret)
- JWK set: JWT key set(非对称加密中需要密钥对)
- JWA: 当前 JWT 所用到的密码学算法
- nonsecure JWT: 当头部签名算法设为 none 时的 JWT(不安全)
2. JWT 的组成结构
一个标准的 JWT 由三部分组成,用点号 (.) 分隔:
xxxxx.yyyyy.zzzzz
2.1 Header (头部)
头部通常由两部分组成:
- 令牌类型(JWT)
- 使用的散列算法(如 HMAC SHA256 或 RSA)
可选部分:
jti: JWT ID,在服务端应当唯一cty: content type(当内容也带有 JWT 时设为 "jwt")
加密方式:
base64UrlEncode(header)
2.2 Payload (载荷)
载荷包含声明(claims),分为三类:
-
Registered Claims(注册声明):
iss(issuer): 发布者的 URL 地址sub(subject): JWT 面向的用户aud(audience): 接受者的 URL 地址exp(expiration): JWT 销毁时间(Unix 时间戳)nbf(not before): JWT 最早可用时间(Unix 时间戳)iat(issued at): JWT 发布时间(Unix 时间戳)jti(JWT ID): JWT 的唯一 ID 编号
-
Public Claims: 由标准化组织根据需要定义
-
Private Claims: 各方之间共享的自定义声明
加密方式:
base64UrlEncode(payload)
安全注意事项:
- 不应在载荷中加入敏感数据(如密码)
- 如需传输敏感数据,应使用 JWE 加密 payload
2.3 Signature (签名)
签名用于验证消息在传输过程中未被篡改。创建签名需要:
- 编码后的 header
- 编码后的 payload
- 密钥(secret)
- 头部中指定的算法
签名算法:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
支持的签名算法类型:
- 对称加密 HMAC(哈希消息验证码):
- HS256/HS384/HS512
- 非对称加密:
- RSASSA(RSA 签名算法):RS256/RS384/RS512
- ECDSA(椭圆曲线数据签名算法):ES256/ES384/ES512
3. JWS (Signed JWT)
JWS 是在 nonsecure JWT 基础上添加签名的 JWT。
3.1 JWS 验证过程
验证签名时,使用公钥或密钥解密签名,并与 base64UrlEncode(header) + base64UrlEncode(payload) 比较,一致则验证通过。
3.2 JWS 额外头部声明(可选)
jku: 发送 JWK 的地址(建议 HTTPS)jwk: JWKkid: JWK 的 ID 编号x5u: 指向 X509 公共证书的 URLx5c: X509 证书链x5t: X509 证书的 SHA-1 指纹x5t#S256: X509 证书的 SHA-256 指纹typ: 类型声明(JOSE 或 JOSE+ JSON)crit: 必须由解析器处理的声明名称数组
3.3 JWS 序列化(多重签名)
当需要多重签名时,使用 JWS 序列化结构:
{
"payload": "<base64UrlEncode(payload)>",
"signatures": [
{
"protected": "<base64UrlEncode(header)>",
"header": "<JWS 额外声明>",
"signature": "<签名>"
}
]
}
4. JWE (Encrypted JWT)
JWE 用于保护数据不被第三方看到,比 JWS 更安全。
4.1 JWE 与 JWS 的区别
| 特性 | JWS | JWE |
|---|---|---|
| 目的 | 验证数据 | 保护数据不被查看 |
| 密钥使用 | 私钥加密,公钥验证 | 公钥加密,私钥解密 |
| 数据修改 | 公钥持有者只能验证 | 公钥持有者可添加新数据 |
4.2 JWE 的构成
JWE 由五部分组成:
<protected header>.<encrypted key>.<initialization vector>.<cipher text>.<authentication tag>
- protected header: 类似 JWS 头部
- encrypted key: 加密密文的对称密钥
- initialization vector: 初始 IV 值
- cipher text: 密文数据
- authentication tag: 防止密文被篡改的附加数据
4.3 JWE 密钥加密算法
JWE 需要两种加密算法:
- 加密密钥的算法
- 加密内容的算法
密钥管理模式:
- Key Encryption
- Key Wrapping
- Direct Key Agreement
- Key Agreement with Key Wrapping
- Direct Encryption
4.4 JWE Header 声明
type: 一般为 "jwt"alg: 加密密钥的算法enc: 加密内容的算法zip: 压缩算法(如 "DEF" 表示 deflate)- 其他与 JWS 相同的声明(jku/jkw/kid/x5u/x5c/x5t/x5t#S256/typ/cty/crit)
4.5 JWE 加密过程
- 根据头部
alg生成随机数 - 根据密钥管理模式确定加密密钥
- 确定 JWE 加密密钥(CEK)
- 计算初始 IV(如需要)
- 压缩明文(如
zip声明存在) - 使用 CEK、IV 和附加认证数据加密内容
- 压缩内容,返回 token
4.6 JWE 序列化
{
"protected": "<base64UrlEncode(header)>",
"unprotected": "<JWS 额外声明>",
"iv": "<base64(IV)>",
"aad": "<额外认证数据>",
"ciphertext": "<base64(加密数据)>",
"recipients": [
{
"header": "<密钥算法声明>",
"encrypted_key": "<JWE 加密密钥>"
}
]
}
5. JWT 工作原理
5.1 认证流程
- 用户使用凭据登录成功后,服务端返回 JWT
- 用户访问受保护资源时,在
Authorization头中携带 JWT:Authorization: Bearer <token> - 服务器验证 token 并返回对应内容
5.2 JWT 存储方式
- HTTP-only Cookie(防 XSS)
- localStorage
- sessionStorage
- Vuex(如使用 Vue)
5.3 跨域问题
使用 Authorization: Bearer 发送令牌不会引起跨域资源共享 (CORS) 问题,因为它不使用 cookie。
6. 算法选择建议
6.1 HMAC vs RSA/ECDSA
| 特性 | HMAC | RSA/ECDSA |
|---|---|---|
| 类型 | 对称加密 | 非对称加密 |
| 适用场景 | 单点登录,一对一 | 一对多(如微服务架构) |
| 速度 | 快 | 相对较慢 |
| 密钥管理 | 单一密钥 | 公钥/私钥对 |
建议:
- 单一应用、单一开发团队:使用 HMAC
- 微服务架构、多团队开发:使用 RSA/ECDSA
6.2 算法选择考虑因素
- 安全性需求:高安全性场景优先选择 RSA/ECDSA
- 性能需求:高吞吐量场景可考虑 HMAC
- 密钥管理复杂度:HMAC 更简单,RSA/ECDSA 需要管理密钥对
- 系统架构:分布式系统更适合 RSA/ECDSA
7. 安全最佳实践
- 不要存储敏感信息在未加密的 payload 中
- 使用 HTTPS 传输 JWT
- 设置合理的过期时间(
exp声明) - 避免使用 none 算法
- 验证所有必需的声明(如
iss,aud,exp等) - 保护密钥:定期轮换,安全存储
- 考虑使用 JWE 传输敏感数据
- 防范重放攻击:可使用
jti和短期有效的 token
8. 总结
JWT 提供了一种简洁、自包含的方式在各方之间安全传输信息。通过 JWS 实现数据验证,通过 JWE 实现数据加密,可以满足不同场景下的安全需求。在实际应用中,应根据具体需求选择合适的算法和实现方式,并遵循安全最佳实践以确保系统安全。