Uvlio

Command Palette

Search for a command to run...

返回文章列表
技术文章

读 JWT:解码能看到什么,又能证明什么

JSON Web Token 是用点连接的三段 base64url 内容:头部、载荷和签名。其中两段任何持有令牌的人都能读——这是这个格式最重要的事实,也是最常被误解的一点。
limitcool 维护的 Uvlio 编辑团队2026-05-177 分钟阅读
主题封面开发工具JWT 生成器JWT 解析工具

读 JWT:解码能看到什么,又能证明什么

JWT 是三段 base64url,解码其中一段并不能说明它是不是真的。怎么读懂各项声明,以及令牌为什么会在 URL 里坏掉。

文章主题预览
理解原理
检查边界
使用工具
关联工具
JWT 生成器JWT 解析工具URL 解析器查询字符串生成器
阅读重点
1理解原理
2检查边界
3使用工具

原创流程图

读 JWT:解码能看到什么,又能证明什么

这张图由 Uvlio 为本文工作流生成,用来说明从输入检查到输出判断的基本路径。
1

理解原理

检查后再进入下一步

2

检查边界

检查后再进入下一步

3

使用工具

检查后再进入下一步

维护与复核
维护者:limitcool。阅读时可重点关注技术原理、处理边界、隐私风险和可验证事实。
编码不是加密

标准签名 JWT 的头部和载荷是 base64url 文本,不是密文。任何拿到令牌的人——从 URL、日志文件、浏览器开发者工具、Referer 头——都能不用任何密钥读出里面的每一项声明。签名保护的是完整性而不是机密性:它能证明令牌没被篡改,但完全不能说明谁有权看它。凡是你不愿意写进日志的内容,就不要放进载荷。

解码不是验签

解析工具做的事是拆分令牌并对两段做 base64 解码。只要输入格式正确,这个操作永远成功,包括对一个手工伪造的令牌。验签是另一步:用密钥或公钥重新计算签名并比对。调试工具给你显示了一份整洁、看起来合理的载荷,并不能证明这个令牌是真的。「因为解码正常所以相信这项声明」,是一整类认证漏洞的根源。

base64url 不是 base64

JWT 用的是 URL 安全字母表:减号和下划线替代加号和斜杠,末尾的等号填充被去掉。把 JWT 粘进标准 base64 解码器,往往会因为填充报错,或者在被替换的字符上把字节弄乱。这也解释了为什么令牌在一个系统里正常、到下一个系统就坏了——中间有人「好心地」修正了编码,或者某个 URL 解码器把合法字符变成了别的东西。

时间声明与时钟问题

exp 是过期时间,iat 是签发时间,nbf 是生效时间。三者都是以秒为单位的 Unix 时间戳,不是毫秒——这是令牌看起来在 1970 年或遥远未来过期的常见原因。由于签发方和验证方的时钟会漂移,实现通常允许几秒的容差。如果令牌总是在刚签发时偶发失败,那么「nbf 声明 + 签发服务器时钟偏快」是首选嫌疑。

令牌为什么会在 URL 里坏掉

放在查询串里的 JWT 会出现在浏览器历史、服务器访问日志,以及发给第三方的 Referer 头里。它同时也很脆弱:令牌很长,部分代理和老客户端会截断超过几千字符的 URL,而被一层编码一次、又被另一层再编码一次的令牌,到达时就已经损坏。如果同一个令牌放在请求头里能用、放进链接就不行,先逐字符比对这两个字符串——答案通常是二次编码。

alg 是一条指令,问题正出在这里

头部声明了签名算法,而幼稚的验证方会读它并照做。由此产生两种经典攻击:一种把 alg 设成 none 并直接去掉签名;另一种把 RS256 令牌换成 HS256,让服务器把公钥当作 HMAC 密钥来验签——而公钥本来就是公开的。两者的修复方式相同:验证方事先决定接受哪种算法,拒绝其他一切,而不是听从它正在检查的那个令牌的指挥。

一套实用的解码流程

令牌异常时,先解码头部和载荷,记下 alg、exp、iat、nbf 以及 audience 或 issuer 声明。确认时钟单位是秒。把正常路径和失败路径的原始令牌字符串逐字符比对。只有在理解载荷之后,才用预期算法和密钥做验签。如果头部里的算法不在允许列表上,直接拒绝,不要尝试验证。

常见问题

JWT 是加密的吗?

标准签名 JWT 不是。载荷是 base64url 文本,任何拿到令牌的人都能读。要加密需要单独的 JWE 格式。

刚解码出来的声明可以直接相信吗?

不可以。解码对伪造令牌同样会成功。只有用正确密钥验签通过,才建立了信任。

从 URL 里复制出来的 JWT 为什么失效了?

通常是编码问题。JWT 用 base64url,URL 解码器或二次编码层可能改动了减号、下划线或填充字符。

令牌一签发就过期,先查什么?

先看 exp 是不是以秒为单位。毫秒时间戳会大一千倍,而秒值被当成毫秒解析会落在 1970 年。