乐闻世界logo
搜索文章和话题

JWT 的签名算法有哪些,如何选择

2026年2月21日 17:52

JWT 的签名算法是保证其安全性的关键,以下是主要签名算法的对比和选择建议:

主要签名算法

1. HS256 (HMAC SHA256)

对称加密算法,使用相同的密钥进行签名和验证。

特点:

  • 性能较好,计算速度快
  • 密钥管理复杂,需要安全地共享密钥
  • 适合单服务应用

示例:

javascript
const token = jwt.sign(payload, 'secret-key', { algorithm: 'HS256' }); const decoded = jwt.verify(token, 'secret-key', { algorithms: ['HS256'] });

适用场景:

  • 单体应用
  • 服务端对服务端的认证
  • 内部系统通信

2. RS256 (RSA SHA256)

非对称加密算法,使用私钥签名,公钥验证。

特点:

  • 安全性更高,私钥不泄露
  • 公钥可以公开分发
  • 密钥管理相对简单
  • 性能较慢

示例:

javascript
const privateKey = fs.readFileSync('private.key'); const publicKey = fs.readFileSync('public.key'); // 签名(使用私钥) const token = jwt.sign(payload, privateKey, { algorithm: 'RS256' }); // 验证(使用公钥) const decoded = jwt.verify(token, publicKey, { algorithms: ['RS256'] });

适用场景:

  • 分布式系统
  • 公共 API
  • 第三方集成
  • 需要高安全性的场景

3. ES256 (ECDSA SHA256)

椭圆曲线数字签名算法,使用私钥签名,公钥验证。

特点:

  • 签名更小(比 RSA 小约 50%)
  • 性能比 RSA 更好
  • 安全性高
  • 密钥生成速度快

示例:

javascript
const privateKey = fs.readFileSync('ec-private.key'); const publicKey = fs.readFileSync('ec-public.key'); const token = jwt.sign(payload, privateKey, { algorithm: 'ES256' }); const decoded = jwt.verify(token, publicKey, { algorithms: ['ES256'] });

适用场景:

  • 移动应用(减少传输数据量)
  • IoT 设备
  • 需要高性能的场景

4. PS256 (RSA-PSS SHA256)

RSA-PSS 签名算法,比 RS256 更安全。

特点:

  • 提供更强的安全性证明
  • 签名大小与 RS256 相同
  • 性能与 RS256 相似

适用场景:

  • 对安全性要求极高的系统
  • 金融、医疗等敏感领域

算法对比

算法类型密钥对签名大小性能安全性推荐度
HS256对称单密钥~32B⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
RS256非对称公私钥~256B⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
ES256非对称公私钥~64B⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
PS256非对称公私钥~256B⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

密钥生成

生成 RSA 密钥对

bash
# 生成私钥 openssl genrsa -out private.key 2048 # 生成公钥 openssl rsa -in private.key -pubout -out public.key

生成 ECDSA 密钥对

bash
# 生成私钥 openssl ecparam -name prime256v1 -genkey -noout -out ec-private.key # 生成公钥 openssl ec -in ec-private.key -pubout -out ec-public.key

选择建议

选择 HS256 的情况

  • 应用规模较小,单服务部署
  • 密钥可以安全地存储和共享
  • 对性能要求极高
  • 内部系统通信

选择 RS256 的情况(推荐)

  • 分布式系统,多服务部署
  • 需要高安全性
  • 公开 API 或第三方集成
  • 标准的 JWT 实现

选择 ES256 的情况

  • 移动应用或 IoT 设备
  • 需要减少传输数据量
  • 对性能有较高要求
  • 签名大小敏感的场景

选择 PS256 的情况

  • 金融、医疗等高安全要求领域
  • 需要最强的安全性证明
  • 不介意性能开销

安全注意事项

  1. 永远不要使用 none 算法

    javascript
    // 危险!不要这样做 const token = jwt.sign(payload, '', { algorithm: 'none' });
  2. 验证时指定算法

    javascript
    // 安全做法 const decoded = jwt.verify(token, key, { algorithms: ['RS256'] // 明确指定允许的算法 });
  3. 使用足够强度的密钥

    • RSA: 至少 2048 位,推荐 3072 或 4096 位
    • ECDSA: 至少 P-256,推荐 P-384 或 P-521
    • HMAC: 至少 256 位
  4. 定期轮换密钥

    • 建议每 6-12 个月轮换一次
    • 实现密钥版本管理
    • 支持多密钥验证(平滑过渡)
  5. 安全存储密钥

    • 使用环境变量或密钥管理服务
    • 不要将密钥提交到代码仓库
    • 限制密钥的访问权限

性能优化建议

  1. 缓存公钥: 验证时缓存公钥,避免重复读取
  2. 使用 ES256: 在安全性和性能之间取得平衡
  3. 批量验证: 对于大量 token,考虑批量验证
  4. 异步验证: 使用异步 API 避免阻塞

通过合理选择签名算法,可以在安全性、性能和易用性之间找到最佳平衡。

标签:JWT