Skip to content

签名密钥管理

概述

签名密钥(Signing Keys)是 Code Bird Cloud 中用于对 OIDC 令牌进行数字签名的核心安全组件。系统使用 ECDSA ES256 算法对 JWT 令牌(包括 Access Token、ID Token)进行签名,确保令牌的完整性和不可伪造性。资源服务器和客户端通过 JWKS(JSON Web Key Set)端点获取公钥来验证令牌的合法性。

核心概念

OIDC 令牌签名

在 OIDC/OAuth 2.1 协议中,身份提供方(Identity Provider)使用私钥对 JWT 令牌进行签名。令牌接收方(如资源服务器、前端应用)通过公开的 JWKS 端点获取对应的公钥,验证令牌签名是否有效。这一机制确保了:

  • 完整性:令牌内容未被篡改
  • 来源可信:令牌确实由 Code Bird Cloud 签发
  • 不可否认性:签发方无法否认已签发的令牌

ES256 算法

Code Bird Cloud 使用 ECDSA(Elliptic Curve Digital Signature Algorithm)的 ES256 变体进行令牌签名:

属性
算法名称ES256
全称ECDSA using P-256 curve and SHA-256 hash
密钥类型EC(Elliptic Curve)
曲线P-256(secp256r1)

与 RSA 相比,ES256 在相同安全级别下具有以下优势:

  • 密钥长度更短(256 位 vs RSA 2048 位)
  • 签名速度更快
  • 生成的签名数据更小,有利于减少令牌体积

密钥列表

系统维护一个签名密钥列表,包含当前活跃密钥和历史保留密钥。

列表字段

字段类型说明
IDstring密钥的唯一标识(Key ID,对应 JWT 头部的 kid 字段)
密钥类型string密钥的类型(如 EC)
算法string签名算法(如 ES256)
状态string密钥状态:active(当前活跃)或 previous(已轮换的旧密钥)
JWKobjectJSON Web Key 格式的公钥数据
创建时间string密钥创建时间(ISO 8601 格式)

状态为 active 的密钥用于签发新令牌;状态为 previous 的密钥仍用于验证旧令牌,直到这些令牌过期。

密钥轮换

密钥轮换(Key Rotation)是定期更换签名密钥的安全操作,旨在限制单一密钥的使用寿命,降低密钥泄露带来的风险。

何时执行轮换

场景说明
定期轮换建议每 90 天执行一次密钥轮换,作为安全最佳实践
密钥泄露如果怀疑私钥可能泄露,应立即执行密钥轮换
安全合规满足安全合规要求中关于密钥管理周期的规定

轮换流程

密钥轮换遵循以下步骤:

1. 生成新密钥
   系统生成新的 ECDSA 密钥对(ES256 算法)

2. 新密钥激活
   新密钥立即设为 active 状态,后续签发的令牌使用新密钥签名

3. 旧密钥保留
   当前活跃密钥状态变为 previous,仍保留在 JWKS 中
   使用旧密钥签发的令牌在有效期内仍可正常验证

4. 清理旧密钥
   待所有使用旧密钥签发的令牌过期后,管理员可手动删除旧密钥

轮换 API

POST /api/v1/signing-keys/rotate

请求示例:

bash
curl -X POST https://your-domain/api/v1/signing-keys/rotate \
  -H "Authorization: Bearer <admin_token>"

成功响应:

json
{
  "code": 0,
  "message": "success",
  "result": {
    "id": "sk_002",
    "status": "active",
    "algorithm": "ES256",
    "created_at": "2025-06-15T08:00:00Z"
  }
}

建议:在业务低峰期执行密钥轮换操作,JWKS 端点会自动包含所有状态的公钥。

删除旧密钥

当旧密钥签发的所有令牌都已过期后,可以删除旧密钥以保持密钥列表整洁。

警告:删除仍有令牌在使用的密钥会导致这些令牌验证失败。删除前请确保:

  • 所有使用该密钥签发的 Access Token 已过期
  • 所有使用该密钥签发的 ID Token 已过期
  • 所有使用该密钥签发的 Refresh Token 已过期或已被刷新

不允许删除当前状态为 active 的密钥。如果尝试删除活跃密钥,API 将返回 400 错误。

JWKS 端点

客户端和资源服务器通过 JWKS 端点获取公钥信息来验证令牌签名:

GET /.well-known/jwks.json

该端点返回当前所有有效签名密钥的公钥部分(包括 activeprevious 状态的密钥)。客户端根据令牌头部的 kid(Key ID)字段匹配对应的公钥进行验证。

JWKS 端点是公开的,不需要认证即可访问。依赖方应通过此端点动态获取公钥,而非硬编码公钥内容。

API 参考

所有管理接口均需要管理员令牌认证:Authorization: Bearer <admin_token>

获取签名密钥列表

GET /api/v1/signing-keys

返回所有签名密钥,包含当前活跃密钥和历史密钥。

轮换签名密钥

POST /api/v1/signing-keys/rotate

生成新的签名密钥并设为活跃状态,当前活跃密钥变为 previous 状态。

删除签名密钥

DELETE /api/v1/signing-keys/:id

删除指定的签名密钥。不允许删除当前活跃密钥。

路径参数类型说明
idstring签名密钥 ID

详细的请求和响应格式请参阅 签名密钥 API 参考

安全最佳实践

  1. 定期轮换:即使没有安全事件,也建议每季度(90 天)轮换一次签名密钥
  2. 及时清理:旧密钥对应的令牌全部过期后,及时删除旧密钥,减少密钥暴露面
  3. 访问控制:仅授权超级管理员管理签名密钥,避免密钥管理权限泄露
  4. 动态获取公钥:依赖方应通过 /.well-known/jwks.json 端点动态获取公钥,切勿硬编码
  5. 监控审计:关注签名密钥相关的操作日志,确保所有密钥操作可追溯
  6. 应急预案:制定密钥泄露应急响应预案,确保可以在最短时间内完成密钥轮换并通知下游服务

相关文档

Released under the MIT License.