MAI SWE · VO Coding / Auth

Microsoft JWT 解码:Base64url、JSON 与签名验证边界

把读取 JWT Header/Payload 与信任 Claims 分开;解释手写 Base64url、严格解析、签名和时效/受众检查。

题目重点:把读取 JWT Header/Payload 与信任 Claims 分开;解释手写 Base64url、严格解析、签名和时效/受众检查。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练版输入为 header.payload.signature 三段 JWS compact;加密 JWE 或 nested JWT 是另一个范围,题目未说明。
  • 本题的‘decode’只把 header/payload 由 Base64url 还原为 UTF-8 JSON 并显示;它不会自动证明 claims 可信。
  • 真正用于认证必须用服务器预先允许的算法与可信密钥验证 JWS,再按应用配置核对 iss、aud、exp、nbf 等 claims;具体策略题目未明确。

解题路线

  1. 先问面试官要实现 raw decode、signature verification,还是完整 authorization;请求示例 token 与允许使用的语言/库,避免把三者混成一个函数。
  2. 对三段做长度与字符集检查,Base64url 把 '-'/'_' 映射到传统 Base64 的 '+'/'/',按长度补合法 padding;长度模 4 为 1 无法形成有效 Base64url 数据,拒绝。手写位组解码时每 4 个 6-bit 字符还原最多 3 个字节,并严格处理最后不足 4 字符。
  3. header/payload 经 UTF-8 严格解码与 JSON 对象解析;限制 token 大小、嵌套深度和重复 JSON key 的解析策略,不能把任意损坏字节静默替换。
  4. 若要验证,JWS 签名的输入是原始编码 header+'.'+编码 payload,不是 JSON 重新序列化后的字节;从服务器 allowlist 确定算法和密钥,不信任 token 自称的 alg/kid 去选择任意本地路径或远程 URL。
  5. 签名通过后再核对签发者、受众、时效和应用权限;客户端可 decode 出用户名仅作展示,不因此获得授权。生产环境优先成熟库,手写 Base64 只作面试算法练习。

手动走一遍

把 payload 一位字符改掉,仍可能 Base64url 解出语法正确的 JSON,却不应通过原 JWS 签名。若把这份未验证的 JSON 里的 role='admin' 当权限,就把‘可读’误当‘可信’。三段 Base64url 先按字节解析,不能对整个 token 一次 Base64 解码。

规模与取舍

token 长度 L:分段、Base64url、UTF-8 与 JSON 解析近 O(L) 时间和空间;验签成本依算法/密钥,不能从题目推断。应给输入大小上限,防深嵌套 JSON 与过大 token 占资源。

易错点与追问

容易失分的边界

  • Base64url decode 成功就认为 token 已认证。
  • 把 JSON 重新格式化后再验签,改变 JWS 签名输入。
  • 由不可信 header 自选 alg='none' 或任意密钥来源。
  • 不核验受众/过期时间却允许访问资源。
  • 手写 Base64 时丢掉 UTF-8 多字节字符或接受非法填充。

继续深挖

  • JWE 五段加密 token 与三段 JWS 的处理差别是什么?
  • kid 用于密钥轮换时怎样防路径/URL 注入?
  • 时钟偏差 leeway 应怎样设并监控?
  • 浏览器端能解码 JWT,为什么仍不能据此给用户授权?

技术参考

✓已复制微信号!