3. JWT 签名算法:对称与非对称体系
JWT 的信任基础建立在签名算法之上。签发方使用密钥对 Payload 和 Header 进行签名,接收方验证签名以确认 Token 未被篡改且来源可信。根据密钥管理方式的不同,主流签名算法分为三大类:HMAC 对称签名、RSA 非对称签名和ECDSA 椭圆曲线签名。每类算法在安全性、性能、密钥分发和分布式适用性上存在显著差异。
3.1 HMAC 对称签名(HS256 / HS384 / HS512)
HMAC(Hash-based Message Authentication Code)基于共享密钥的对称签名算法。签发和验证使用同一个密钥,算法将密钥与消息混合后通过哈希函数生成固定长度的签名。
| 算法标识 | 底层哈希函数 | 签名长度(位) | 安全强度 |
|---|---|---|---|
| HS256 | SHA-256 | 256 | 高(推荐) |
| HS384 | SHA-384 | 384 | 更高 |
| HS512 | SHA-512 | 512 | 最高 |
核心特征:HS256 是 JWT 规范中默认且最广泛使用的对称算法。HS384/HS512 提供更高的哈希碰撞抵抗,但计算开销更大,在分布式场景中收益有限。
3.1.1 对称签名的优势与局限
- 优势:计算速度快,签名和验证延迟低;实现简单,无需复杂的密钥对管理。
- 局限:密钥必须在签发方和所有验证方之间共享,分布式系统中密钥分发和轮换困难;一旦密钥泄露,攻击者可伪造任意 Token。
- 适用场景:单体应用、内部微服务之间通过可信网络通信、服务实例数较少且密钥可控的环境。
安全警告:在分布式鉴权系统中,HS256 的共享密钥模式会放大密钥泄露风险。每个验证节点都持有完整密钥,攻击面随节点数量线性增长。生产环境建议优先使用非对称算法。
3.2 RSA 非对称签名(RS256 / RS384 / RS512)
RSA 非对称签名使用私钥签名、公钥验证的密钥对机制。签发方持有私钥,任何接收方只需持有公钥即可验证签名,无需共享敏感密钥。
| 算法标识 | 底层哈希函数 | 密钥长度建议 | 签名长度 |
|---|---|---|---|
| RS256 | SHA-256 | 2048 位 | 256 字节 |
| RS384 | SHA-384 | 2048 位 | 256 字节 |
| RS512 | SHA-512 | 2048 位 | 256 字节 |
行业标准:RS256 是 OAuth 2.0 和 OpenID Connect 规范中的推荐算法,也是大多数生产级鉴权系统的默认选择。
3.2.1 非对称签名的核心优势
- 密钥分离:私钥仅存在于签发服务(如认证中心),验证服务只持有公钥,私钥泄露风险大幅降低。
- 公钥分发:公钥可通过 JWKS(JSON Web Key Set)端点安全分发,支持动态轮换。
- 分布式友好:任意数量的微服务均可独立验证 Token,无需与签发方实时通信。
3.2.2 性能对比
RSA 签名操作(私钥运算)比 HMAC 慢 10-100 倍,但验证操作(公钥运算)相对较快。在分布式鉴权中,验证频率远高于签发频率,因此整体性能可接受。
// RS256 签名示例(Node.js jsonwebtoken 库)
const jwt = require('jsonwebtoken');
const fs = require('fs');
const privateKey = fs.readFileSync('private.pem');
const token = jwt.sign(
{ sub: 'user123', role: 'admin' },
privateKey,
{ algorithm: 'RS256', expiresIn: '1h' }
);
// 验证方使用公钥
const publicKey = fs.readFileSync('public.pem');
const decoded = jwt.verify(token, publicKey, { algorithms: ['RS256'] });
console.log(decoded.sub); // 'user123'
3.3 ECDSA 椭圆曲线签名(ES256 / ES384 / ES512)
ECDSA(Elliptic Curve Digital Signature Algorithm)基于椭圆曲线密码学的非对称签名算法。相比 RSA,ECDSA 在同等安全强度下使用更短的密钥和更小的签名,计算效率更高。
| 算法标识 | 椭圆曲线 | 密钥长度 | 签名长度 | 安全强度(与 RSA 对比) |
|---|---|---|---|---|
| ES256 | P-256 | 256 位 | 64 字节 | ≈ RSA 3072 |
| ES384 | P-384 | 384 位 | 96 字节 | ≈ RSA 7680 |
| ES512 | P-521 | 521 位 | 132 字节 | ≈ RSA 15360 |
推荐选择:ES256(P-256 曲线)在安全性和性能之间达到最佳平衡,是 JWT 分布式鉴权中替代 RS256 的优选方案。签名长度仅为 RS256 的 1/4,显著减少网络传输开销。
3.3.1 ECDSA 的分布式优势
- 签名紧凑:64 字节签名(ES256)远小于 256 字节的 RSA 签名,适合高吞吐、低延迟的微服务通信。
- 密钥生成快:椭圆曲线密钥对生成速度比 RSA 快 10 倍以上,适合频繁轮换密钥的场景。
- 计算效率:同等安全强度下,ECDSA 签名和验证速度均优于 RSA。
3.4 三类签名算法对比总览
| 对比维度 | HMAC(HS256) | RSA(RS256) | ECDSA(ES256) |
|---|---|---|---|
| 密钥类型 | 对称(共享密钥) | 非对称(私钥+公钥) | 非对称(私钥+公钥) |
| 签名长度 | 32 字节 | 256 字节 | 64 字节 |
| 签名速度 | 极快 | 慢 | 中等 |
| 验证速度 | 极快 | 中等 | 中等偏快 |
| 密钥分发难度 | 高(需安全通道) | 低(公钥可公开) | 低(公钥可公开) |
| 分布式适用性 | 低 | 高 | 高 |
| 密钥轮换复杂度 | 高(所有节点同步) | 低(仅更新公钥) | 低(仅更新公钥) |
| 推荐场景 | 单体/内部可信网络 | 通用分布式鉴权 | 高性能/低带宽分布式 |
3.5 签名算法选择决策流程
3.6 分布式鉴权中的算法选型建议
生产级推荐:在分布式微服务架构中,优先选择 RS256 或 ES256。RS256 生态成熟、兼容性最好;ES256 在性能敏感场景中更具优势。避免在跨服务边界使用 HS256。
3.6.1 算法迁移路径
如果现有系统使用 HS256,迁移到非对称算法的推荐步骤:
- 双算法过渡期:签发方同时使用 HS256 和 RS256 签名,验证方接受两种算法。
- 客户端更新:逐步引导客户端使用新的 RS256 Token。
- HS256 下线:确认所有客户端迁移完成后,关闭 HS256 签发,仅保留 RS256。
- 密钥轮换:建立定期轮换私钥的机制,通过 JWKS 端点动态分发公钥。
3.6.2 算法与密钥长度对照
| 算法 | 密钥长度(位) | 签名长度(字节) | 安全寿命估计 |
|---|---|---|---|
| HS256 | 256 | 32 | 2030 年 |
| RS256 | 2048 | 256 | 2030 年 |
| ES256 | 256 | 64 | 2030 年 |
| RS384 | 3072 | 384 | 2035 年 |
| ES384 | 384 | 96 | 2035 年 |
安全提示:对于 2025 年之后的系统,建议使用至少 256 位安全强度的算法。ES256 和 RS256 均满足当前安全标准。如果系统需要运行超过 10 年,考虑 ES384 或 RS384。