跳转到主要内容
CuteJSON
↑↓ 导航 Enter 选择 Esc 关闭

JWT 如何工作: 头部、载荷、签名

发布 1 分钟阅读 作者 Akash Kinkar Pandey

JSON Web Token(RFC 7519)是一种紧凑的方式,将一组声明从一个 方携带到另一方,以便接收方可以信任发送者,或者至少检查 在传输过程中没有任何变化。你在 Authorization: Bearer 头中看到的每个 JWT 都是相同的三个部分用点连接: header.payload.signature。

三个部分

头部和载荷各是一个 JSON 对象,base64url 编码。头部 命名签名算法和令牌类型,通常是像 {"alg":"HS256","typ":"JWT"} 这样小的对象。载荷包含声明: 令牌实际 携带的数据,加上几个具有预定义含义的注册名称,iss(签发者)、 sub(主题)、aud(受众)、iat(签发时间)、nbf(不早于)和 exp(过期)以及 jti(令牌 ID)。规范没有要求任何这些, 除了签发者选择包含的内容,这就是为什么来自两个不同服务的两个 JWT 可以携带完全不同的声明。

签名根本不是 JSON。它是运行头部和载荷(仍以其编码形式) 通过头部中命名的算法的输出,HS256(使用共享密钥的 HMAC)和 RS256/ES256(使用私钥的 RSA 或 ECDSA)是你最常遇到的。Base64url 解码签名给你原始字节,没有更多可读的结构。

编码不是加密

Base64url 是编码,不是密码。任何持有 JWT 的人都可以用文本编辑器 解码头部和载荷,这正是 JWT Decoder 所做的。 这意味着 JWT 永远不是你不会放入 URL 的东西的合适位置: 密码、 信用卡号码、未经同意暴露的全名。如果载荷需要保密 而不仅仅是防篡改,那就需要 JSON Web 加密令牌, 一种不同且不太常见的格式,而不是使用更强算法的签名 JWT。

解码不能说明信任

这是解码器最受指责的部分,所以值得清楚说明: 从 JWT 中读取声明不能证明令牌是否真实。验证签名意味着 用令牌实际签名的实际密钥或公钥重新计算它,并逐字节 检查它是否匹配。只在点上分割令牌并 base64url 解码 三部分中两部分的解码器(每个纯客户端解码器都这样做), 无法访问该密钥,因此无法进行该检查。它可以告诉你 令牌声称什么。它不能告诉你是否应该相信它。

格式良好、解码清晰的令牌仍然可能是伪造的、过期的,或 用从未打算签发它的密钥签名的。exp 和 nbf 值得在 每次解码时检查,正是因为这个原因: 超过其过期时间的令牌, 或尚未有效的令牌,无论其签名是否通过检查都是无效的, 并且将这两个字段读取为它们所代表的时间戳 而不是原始数字是快速一眼抓住它的最快方式。

这有什么用

尽管有此限制,不验证的解码有实际的日常用途: 在调试 API 集成时读取访问令牌被授予的范围, 检查你的应用刚收到的令牌是否真的过期 (而不是从模糊的 401 猜测),或者在决定你的服务是否需要信任 第三方令牌的内容之前检查其内容。这些都不需要签名密钥, 只需要令牌本身。

将其粘贴到 JWT Decoder 中,它将头部、 注册声明和剩余载荷分到自己的行中,立即标记过期或 尚未有效的令牌,并显示原始签名字节, 而不假装已经对任何内容进行了检查。

返回所有文章