前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库JWT alg none 算法混淆攻击 防御
身份身份与权限身份认证与授权

JWT 验证中 alg=none 与 RS256/HS256 算法混淆攻击是如何发生的,如何防御?

攻击者篡改JWT头部将alg设为none或从RS256改为HS256,利用服务端未强制算法白名单的漏洞绕过验签。防御核心是固定允许算法列表并区分签名密钥用途。

前端进阶之旅 · 一题精讲更新于 2026.09.05
身份与权限#身份认证与授权#安全
先看核心答案
理解线索

算法混淆攻击根因

  1. 篡改alg攻击者改头部并重签或删签
  2. 服务端信任未校验算法有效性
  3. 密钥误用公钥当对称密钥

只要是签名,算法和密钥必须匹配,不能依赖头部自描述。

核心回答

先记住这个答案

JWT验证中alg=none攻击指攻击者删去签名并将alg改为none,若服务端未禁用none则接受。RS256/HS256混淆指攻击者用公钥作为HS256密钥对token签名,若服务端允许HS256并误用公钥校验则通过。防御:服务端只接受白名单算法,且校验时必须按算法类型使用对应密钥,不信任头部字段。

  • 必须禁用none且白名单算法
  • 公钥绝不可用作HMAC密钥
  • 验证前强制检查alg字段

两类篡改手法解析

JWT由头部、载荷、签名三部分构成,验证时取头部alg的算法值来验签。若服务端不限制alg取值,攻击者可把alg改为none并去掉签名段,有些库会跳过校验直接信任。更隐蔽的是算法混淆:一个用RS256签发的合法token,攻击者修改alg为HS256,并用服务端公钥作HMAC密钥重签,因服务端多数持有公钥,若误允许HS256,验证就会通过。

根因是服务端未将算法选择视为不可信输入。正确做法是验证前先检查alg是否在预设白名单,并且算法对应的密钥类型必须明确:RS256对应公钥验签,HS256对应共享密钥,不能混用。RFC 7518也建议明确声明kid并绑定密钥。

一个被绕过的实际配置

某API使用RSA私钥签发token,验证中间件配置为“支持RS256和HS256”以便兼容旧客户端。攻击者截获一个合法RS256 token,把alg从RS256改成HS256,然后从开放接口拿到该应用的公钥文件,用公钥字符串作密钥,按HS256算法重新计算签名,替换后发送。

服务端在验签时,头部的alg只告诉它用HS256,于是它拿配置中的共享密钥去校验,而配置中共享密钥常被错误地等于公钥内容,结果验签通过,攻击者成功伪装。修复办法是只保留RS256一个算法,并验证kid指向RS256专用密钥,彻底关闭HS256入口。

适用与失效边界

算法混淆攻击的前提是服务端在验签逻辑中同时接受对称与非对称算法,且将验签密钥暴露给客户端或可从公共渠道获得。如果服务端只用独立的共享密钥做HMAC,不涉及公钥,就没法混淆;如果已锁定单一alg,攻击会因白名单拒绝而失败。

但完全依赖白名单并非万无一失:若密钥泄露、库解析缺陷或错误处理绕过都可使防护失效。因此还需配合签名算法强制声明、JWT库安全配置以及监控异常alg组合。防御成本低,嵌入开发规范即可,但需对所有历史签发token同步检查。

回答前,多想一步

容易答错的地方

alg=none只影响老库
误区:alg=none只在老版本库中有效,现代库已免疫。纠正:虽然官方库默认禁用none,但不少开发者在验证逻辑中手动处理异常,或自定义解密路径时忽略校验,仍可能触发。只要头部可控,就需显式拒绝。
混淆仅限RS256/HS256
误区:算法混淆只存在于RS256/HS256之间。纠正:任何非对称算法与对称算法组合都可能,如ES256与HS256同理。关键在于服务端是否接受多种算法并复用同一公钥当对称密钥。
试着用自己的话回答

面试官还会怎么问?

如何编写安全的JWT验证逻辑?

固定允许算法列表,如['RS256'],先校验alg属于该列表再匹配公钥;避免动态分支使用头部token。同时为每个密钥绑定一个kid,并用kid找到对应公钥,公钥与算法强关联。

HS256密钥与RS256公钥泄露的后果有何区别?

RS256公钥可公开,但只能验签不能签名;HS256密钥是共享机密,泄露后攻击者可任意签发。混淆攻击正是把公钥当对称密钥,使公钥变相成为可签名机密,破坏认证完整性。

必须同时支持多种算法时如何防御?

用kid作为唯一分发索引,每个kid明确算法类型和密钥材料,服务端根据kid直接取密钥对象,不允许前端指定算法。同时安装加密库并开启强制算法保护,拒绝未知alg。

从一道题,走向一组知识

把知识连起来

身份认证与授权

JWT 的三个部分分别是什么,服务端验证 JWT 时具体校验哪些内容?

理解JWT三部分结构与签名验证顺序,才能明白攻击者篡改alg后验签过程如何被误导。

身份认证与授权

HS256 的 JWT 密钥应该如何生成、存储和轮换,硬编码在代码里有什么风险?

密钥管理确保HS256密钥保密和RS256公钥私钥分离,从源头阻断混淆攻击中公钥被当机密使用。

参考资料

  • ¶

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 两类篡改手法解析
  3. 一个被绕过的实际配置
  4. 适用与失效边界
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑