乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • JWT 基础

    • JWT 概述
    • JWT 结构详解
  • 签名与加密

    • JWS 签名基础
    • RS256与ES256签名
    • JWE 加密
  • 密钥管理

    • JWK 与密钥管理
  • 算法原理

    • 核心算法详解
  • 实战与安全

    • JWT 实际应用
    • JWT 安全攻防

JWK 与密钥管理

当广州飞翔科技(learnto.cn)的微服务集群从 5 个扩展到 50 个时,后端开发小崔遇到了一个头疼的问题:每个服务都硬编码了验证 JWT 的公钥,轮换密钥时需要重新发布所有服务。架构师白歌看了一眼他的代码说:"你需要 JWK(JSON Web Key,JSON Web 密钥) 和 JWKS(JSON Web Key Set,JSON Web 密钥集) 。把密钥集中管理,通过端点分发,服务启动时动态拉取。"

本章将介绍 JWK 的结构、密钥类型、JWKS 集合,以及 JWS/JWE 头部中引用密钥的各种声明。


JWK 的结构

JWK 是一个 JSON 对象,包含描述密钥所需的一系列参数。不同密钥类型的参数各不相同,但以下通用参数适用于所有 JWK:

参数全称说明
ktyKey Type(密钥类型)必需。区分密钥类型:EC(椭圆曲线)、RSA(RSA 密钥)、oct(对称密钥)
usePublic Key Use(公钥用途)可选。sig 表示用于签名,enc 表示用于加密
key_opsKey Operations(密钥操作)可选。详细指定用途,如 sign、verify、encrypt、decrypt、wrapKey、unwrapKey 等。不应与 use 同时使用
algAlgorithm(算法)可选。打算与该密钥配合使用的算法,如 RS256、ES256、A256GCM
kidKey ID(密钥标识符)可选。密钥的唯一标识符,用于在 JWKS 中快速定位特定密钥
x5uX.509 URL可选。指向 PEM 编码的 X.509 证书或证书链的 URL
x5cX.509 Certificate Chain可选。Base64 编码的 X.509 DER 证书数组
x5tX.509 Certificate SHA-1 Thumbprint可选。证书的 SHA-1 指纹
x5t#S256X.509 Certificate SHA-256 Thumbprint可选。证书的 SHA-256 指纹

示例 JWK(椭圆曲线公钥):

{
  "kty": "EC",
  "crv": "P-256",
  "x": "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
  "y": "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
  "use": "enc",
  "kid": "feixiang-ec-key-01"
}

三种密钥类型

JWA(JSON Web Algorithms)规范定义了三种主要的 JWK 密钥类型:

EC:椭圆曲线密钥(Elliptic Curve Key)

用于 ECDSA 签名和 ECDH 密钥协商。核心参数包括:

  • crv :曲线名称,如 P-256、P-384、P-521。
  • x 、**y** :公钥的坐标点。
  • d :私钥值(仅私钥 JWK 包含)。

飞翔科技场景 :小崔为乐途运动 App 生成了一套 ECDSA 密钥,公钥以 JWK 格式发布到密钥端点,供移动端 SDK 下载验证令牌。

RSA:RSA 密钥

用于 RSASSA 签名和 RSAES 加密。核心参数包括:

  • n :模数(modulus),大整数。
  • e :公钥指数(public exponent),通常为 AQAB(即 65537)。
  • d :私钥指数(private exponent,仅私钥)。
  • p 、 q 、 dp 、 dq 、 qi :CRT(中国剩余定理)参数,加速私钥运算(仅私钥)。

示例 RSA 公钥 JWK:

{
  "kty": "RSA",
  "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
  "e": "AQAB",
  "alg": "RS256",
  "kid": "feixiang-rsa-key-2024"
}

oct:对称密钥(Octet Sequence Key)

用于 HMAC 签名和 AES 加密。只有一个核心参数:

  • k :密钥值,Base64-URL 编码。

示例对称密钥 JWK:

{
  "kty": "oct",
  "k": "GawgguFygrWKfh7pI8l3fQ",
  "alg": "HS256",
  "kid": "feixiang-hmac-key-internal"
}

安全提示 :对称密钥的 JWK 应严格限制访问权限,仅在受信任的服务间共享。飞翔科技的内部 Kubernetes 集群中,oct 类型的 JWK 通过 Sealed Secrets 加密存储。


JWKS:JSON Web Key Set

单个 JWK 可以描述一把密钥,但实际系统中通常需要多把密钥(例如新旧密钥同时存在以实现平滑轮换)。 JWKS 就是一个包含多个 JWK 的 JSON 对象,顶层有一个 keys 数组:

{
  "keys": [
    {
      "kty": "EC",
      "crv": "P-256",
      "x": "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
      "y": "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
      "use": "enc",
      "kid": "feixiang-ec-key-01"
    },
    {
      "kty": "RSA",
      "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
      "e": "AQAB",
      "alg": "RS256",
      "kid": "feixiang-rsa-key-2024"
    }
  ]
}

飞翔科技场景 :小崔在 https://learnto.cn/.well-known/jwks.json 部署了 JWKS 端点。所有内部服务启动时自动拉取该端点,根据 kid 匹配令牌头部中的密钥标识符,完成验证。当白歌决定轮换 RSA 密钥时,只需在 JWKS 中新增一个 kid 为 feixiang-rsa-key-2025 的条目,旧密钥保留一段时间供未过期令牌使用,服务无需重新部署。


JWS 头部中的密钥引用声明

JWS 和 JWE 规范提供了多种在头部中引用密钥的方式,使验证方无需硬编码密钥:

声明全称用途
jkuJWK Set URL指向 JWKS 端点的 URI。验证方通过 HTTP GET 获取密钥集合
jwkJSON Web Key直接将公钥以 JWK 格式嵌入令牌头部
kidKey ID密钥标识符,与 JWKS 中的 kid 匹配以选取特定密钥
x5uX.509 URL指向 PEM 编码的 X.509 证书链的 URL
x5cX.509 Certificate Chain直接在头部中嵌入 Base64 编码的 X.509 证书数组
x5tX.509 Certificate SHA-1 Thumbprint用 SHA-1 指纹引用证书
x5t#S256X.509 Certificate SHA-256 Thumbprint用 SHA-256 指纹引用证书(推荐)

飞翔科技场景 :

  • 小崔在内部服务间使用 kid+jku 的组合:令牌头部携带 kid,验证方从统一的 JWKS 端点拉取密钥集合,按 kid 索引找到正确的公钥。
  • 白歌在与外部合作伙伴对接时,选择在头部中直接嵌入 jwk ,减少对方系统的依赖,但代价是令牌体积增大。
  • 李眉在支付网关使用 x5c 嵌入完整的证书链,因为金融合规要求提供可审计的证书信任链。

密钥管理的最佳实践

小崔在飞翔科技内部 wiki 中整理了 JWK/JWKS 的使用规范:

  1. 始终使用 kid :即使只有一个密钥,也要设置 kid,为未来的密钥轮换预留空间。
  2. 优先使用 jku 而非硬编码 :验证方应从可信的 JWKS 端点动态获取公钥,而不是把公钥写死在配置文件里。
  3. HTTPS 传输 jku 和 x5u :获取密钥的链路必须使用 TLS,防止中间人篡改公钥。
  4. 密钥轮换策略 :新密钥加入 JWKS 后,旧密钥保留一个令牌最大生命周期(如 24 小时)再移除,避免正在流通的令牌失效。
  5. 私钥永不离开签发服务 :JWK 格式的私钥(包含 d 参数)只存在于签发服务的内存或安全密钥库(HSM、KMS)中,绝不通过 API 暴露。

白歌的总结 :"JWT 的安全性不只在算法选择,更在密钥管理。JWK 和 JWKS 给了我们一个标准化的密钥分发框架,但框架本身不能替代安全运维——HTTPS、访问控制、密钥轮换,一个都不能少。"


小结

  • JWK 是 JSON 格式的密钥描述,统一了 EC、RSA、对称密钥的表示方式。
  • JWKS 通过 keys 数组管理多个密钥,是微服务架构中实现密钥轮换的基础设施。
  • JWS/JWE 头部声明 (jku、jwk、kid、x5u、x5c、x5t 等)提供了灵活的密钥引用机制,使验证方能够动态定位正确的公钥。
  • 飞翔科技通过统一的 JWKS 端点,实现了 50+ 微服务的密钥集中管理,大幅降低了运维复杂度。