3. JWT Header 详解:typ 类型声明、alg 签名算法声明、常见算法类型
JWT Header(头部)是 JWT 结构的第一个组成部分,位于令牌的最前端。它是一个 JSON 对象,经过 Base64URL 编码后形成令牌的第一段。Header 承载了关于令牌本身的核心元数据,包括令牌类型(typ)和签名算法(alg),是验证方正确解析和验证 JWT 的“说明书”。
3.1 Header 结构概览
一个标准的 JWT Header 通常包含两个注册声明:typ 和 alg。其 JSON 结构如下:
{
"alg": "HS256",
"typ": "JWT"
}
经过 Base64URL 编码后,该 Header 变为:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
解码后即可还原为原始的 JSON 对象。验证方必须首先解码 Header,读取 alg 字段,才能使用正确的算法和密钥来验证签名。
3.2 typ(Type)类型声明
typ(Type)声明用于明确表示该令牌的类型,帮助验证方区分 JWT 与其他类似令牌格式(如 JWE)。其值通常为 "JWT",表示这是一个 JSON Web Token。
| 字段 | 说明 | 推荐值 |
|---|---|---|
typ |
令牌类型声明,用于标识令牌的媒体类型 | "JWT" |
cty |
内容类型声明,用于嵌套 JWT 场景 | "JWT"(嵌套时使用) |
实践建议:在大多数 API 场景中,
typ 字段可以省略,因为验证方通常默认期望 JWT。但为了契约的清晰性和可扩展性,建议始终显式声明 "typ": "JWT"。
3.3 alg(Algorithm)签名算法声明
alg(Algorithm)声明是 Header 中最关键的字段,它指定了用于签名或加密 JWT 的算法。验证方必须严格遵循该字段指定的算法进行签名验证,否则可能导致严重的安全漏洞。
alg 字段的值是一个字符串,取自 JWA(JSON Web Algorithm)注册表。常见的算法类型分为三大类:
3.4 常见算法类型对比
| 算法类别 | alg 值 | 算法名称 | 密钥类型 | 签名/加密 | 安全性 |
|---|---|---|---|---|---|
| HMAC | HS256 |
HMAC with SHA-256 | 对称密钥(共享密钥) | 签名 | 高 |
HS384 |
HMAC with SHA-384 | 对称密钥(共享密钥) | 签名 | 更高 | |
HS512 |
HMAC with SHA-512 | 对称密钥(共享密钥) | 签名 | 最高 | |
| RSA | RS256 |
RSA with SHA-256 | 非对称密钥(公钥/私钥) | 签名 | 高 |
RS384 |
RSA with SHA-384 | 非对称密钥(公钥/私钥) | 签名 | 更高 | |
RS512 |
RSA with SHA-512 | 非对称密钥(公钥/私钥) | 签名 | 最高 | |
| ECDSA | ES256 |
ECDSA with P-256 | 非对称密钥(公钥/私钥) | 签名 | 高(更小签名) |
ES384 |
ECDSA with P-384 | 非对称密钥(公钥/私钥) | 签名 | 更高 | |
ES512 |
ECDSA with P-521 | 非对称密钥(公钥/私钥) | 签名 | 最高 | |
| None | none |
无签名 | 无密钥 | 无 | 极低(仅用于测试) |
安全警告:严禁在生产环境中使用
"alg": "none"。攻击者可能通过篡改 Header 中的 alg 为 none 来绕过签名验证,导致令牌伪造。验证方必须显式拒绝 none 算法。
3.5 算法选择决策流程
选择签名算法时,需要综合考虑安全性、性能、密钥管理复杂度等因素。以下决策流程可以帮助你做出合理选择:
- 是否需要非对称密钥?
- 是:多个服务需要独立验证令牌,且不希望共享密钥 → 选择 RSA 或 ECDSA
- 否:只有签发方和验证方两方,可以安全共享密钥 → 选择 HMAC
- 签名大小是否敏感?
- 是:令牌需要频繁传输,带宽受限 → 优先选择 ECDSA(签名更短)
- 否:签名大小不是瓶颈 → RSA 或 HMAC 均可
- 计算性能要求?
- 高并发验证场景 → HMAC 性能最优,ECDSA 次之,RSA 相对较慢
- 推荐默认值:大多数微服务场景推荐
RS256或ES256,兼顾安全性与密钥分发便利性。
3.6 Header 在 JWT 中的位置与作用
以下 SVG 图展示了 JWT 的整体结构,并突出 Header 在令牌中的位置及其与 Payload、Signature 的关系:
3.7 常见算法选择对比
为了更直观地理解不同算法在实际应用中的差异,下表从密钥管理、性能、签名长度三个维度进行对比:
| 对比维度 | HMAC(HS256) | RSA(RS256) | ECDSA(ES256) |
|---|---|---|---|
| 密钥管理 | 共享密钥,分发困难 | 公钥/私钥对,分发简单 | 公钥/私钥对,分发简单 |
| 签名性能 | 快 | 慢 | 中等 |
| 验证性能 | 快 | 慢 | 中等 |
| 签名长度 | 32 字节 | 256 字节 | 64 字节 |
| 适用场景 | 内部服务间通信 | 开放 API、第三方集成 | 移动端、IoT、带宽敏感场景 |
3.8 安全最佳实践
- 白名单算法:验证方应维护一个允许的算法白名单,拒绝白名单之外的任何
alg值。 - 拒绝 none:始终检查并拒绝
"alg": "none",即使是在开发环境中。 - 密钥轮换:定期轮换签名密钥,并在 Header 中使用
kid(Key ID)字段标识使用的密钥。 - 算法固定:在服务端代码中固定期望的算法,不要直接从 Header 中读取
alg后直接用于验证,防止算法混淆攻击。
核心要点:Header 中的
alg 字段是 JWT 安全验证的“门锁”。验证方必须严格校验该字段,并使用白名单机制防止算法篡改攻击。推荐生产环境使用 RS256 或 ES256,避免使用 HS256 在多方场景下共享密钥。