1. 整体设计:802.11i 安全框架到底解决了什么问题
先说结论:802.11i 就是 WPA2 背后的协议标准,我们日常连 Wi-Fi 时输入的密码、路由器上配置的加密方式,最终都要落在 802.11i 定义的这套安全机制上。它解决的不是“密码有多长”,而是“密码怎么变成真正加密数据的钥匙”。这个问题的难度,比大多数人想象的要大得多。
在 802.11i 出现之前,WEP 用的是静态密钥 RC4 加密,密钥一旦泄露,整个网络的加密就形同虚设。更致命的是 WEP 的 IV(初始化向量)只有 24 位,在稍微繁忙一点的环境里,几小时内就会出现 IV 重复,攻击者只需要收集足够多的重复 IV 数据包,就能反推出密钥流。这套方案从根上就是错的,补丁根本无法救活它。
所以 802.11i 的架构思路做了几个关键转变:第一,密钥不再是静态的,而是通过一次握手续订;第二,引入 802.1X 认证框架,把“接入认证”和“密钥协商”分离;第三,加密算法从 RC4 迁移到 AES-CCMP,从流密码转向分组密码。这三个转变直接定义了后面十几年 Wi-Fi 安全的基本形态。
对于做无线安全研究、网络运维或者取证分析的人来说,理解 802.11i 的价值不只是看懂合规文档,而是能回答几个非常实际的问题:
- 当 Wireshark 里出现 EAPOL 报文时,你能判断这条链路是否安全吗?
- 攻击者离线破解 Wi-Fi 密码时,他到底在破解什么数据?
- 为什么有人拿到了 PMKID 就能绕过 4 次握手?
- 企业网络里用户频繁掉线,很多时候跟组密钥握手超时有关,你能否从抓包里定位原因?
这篇文章我会把 4 次握手和组密钥握手从设计目的、消息结构、密钥派生算法到抓包实操完整拆开讲,最后附上我在排查和一些安全测试中遇到的真实问题记录。准备工作中需要 Wireshark、一个支持监听模式的无线网卡,以及一颗愿意较真的心。
1.1 RSNA 体系里的密钥层级
802.11i 定义的安全机制叫 RSNA(Robust Security Network Association),翻译过来是“稳健安全网络关联”。这个词听起来抽象,其实含义很直接:建立关联的过程必须经过认证,并且所有数据都要用协商出来的密钥加密。
RSNA 体系里最核心的是三把钥匙:PMK(Pairwise Master Key)、PTK(Pairwise Transient Key)和 GTK(Group Temporal Key)。它们的层级关系可以用一个不太严谨但好记的类比:PMK 是“根信任”,PTK 是“两人之间的通话密钥”,GTK 是“广播室的大喇叭密钥”。
PMK 的产生有两条路径。个人网络(WPA2-PSK)里,PMK 由预共享密钥(PSK)通过 PBKDF2 派生得到,输入是 SSID 和密码;企业网络(WPA2-Enterprise)里,PMK 由认证服务器在 802.1X 流程结束后下发。PMK 本身不直接在无线链路上传输,它只参与后续的密钥派生,这也是整个机制安全性的基石。
PTK 是站点(STA)和接入点(AP)之间专用的会话密钥,长度视加密算法而定:CCMP 场景下为 384 位,TKIP 场景下为 512 位。PTK 由 PMK、双方 MAC 地址、两个随机数(ANonce 和 SNonce)共同通过伪随机函数生成。这个设计精妙在于:即使 PMK 不变,只要随机数变化,每次会话的 PTK 就完全不同。
GTK 则是服务多个站点的组播/广播密钥。AP 每次生成新的 GTK 后,需要通过组密钥握手安全地分发给已认证的站点。很多人在分析 Wi-Fi 抓包时只盯着数据帧,忽略了组密钥更新过程,这是不对的——不理解 GTK 分发机制,你就看不明白 802.11 帧里的广播流量为什么突然全部解密失败。
1.2 为什么非要用四次握手而不是两次
很多初学者会问:既然 PTK 是由 PMK 和随机数算出来的,为什么不能像 TLS 一样两次握手搞定?这个问题的答案需要从“密钥确认”和“双方公平性”两个角度理解。
先看密钥确认:握手过程中,双方的密钥是否一致,必须通过实际消息验证。具体来说,PTK 里会拆出 KCK(密钥确认密钥)和 KEK(密钥加密密钥),KCK 用于计算消息完整性校验。如果双方算出的 KCK 不同,握手消息的 MIC 校验就会失败,协商自然中断。这个 MIC 能证明“我手里的 PMK 和你手里的 PMK 一致”,这是不需要传输 PMK 本身就能完成的工作。
再看双方公平性:如果只有两次握手,比如 AP 直接发送一个随机数、站点回复一个随机数,那么 AP 可能先持有密钥而对站点一无所知;或者站点在密钥确认之前就开始发送数据。4 次握手让双方都能确认:
- 第 1 次:AP 发送 ANonce,宣告自己有 PMK,但还没验证;
- 第 2 次:站点回复 SNonce,并附上自己的 MIC,证明“我知道 PMK”;
- 第 3 次:AP 校验站点 MIC 后,发送自己的 MIC,并携带安装 PTK 的指示;
- 第 4 次:站点确认 AP 的 MIC,并回复确认帧,双方开始使用 PTK 加密数据。
这四次消息环环相扣,任何一次丢失都会导致重新协商。从安全角度上说,第 4 次消息没有携带新信息,只是为了让 AP 确认站点已经装好 PTK,防止 AP 先进入加密状态而站点还处于未配置状态造成的“半开”问题。
2. 4 次握手逐条拆解:消息结构、密钥派生与验证机制
真正打开 Wireshark 看 EAPOL 帧时,你会发现 4 次握手并不是四条长得一模一样的数据包。每条消息的功能不同,字段取值也有明显差异。先用表格梳理一下整体流程,再逐条分析。
| 消息序号 | 发送方 | 携带内容 | 主要作用 |
|---|---|---|---|
| Message 1 | AP → STA | ANonce、Key Replay Counter | 向站点发起握手,提供 AP 随机数 |
| Message 2 | STA → AP | SNonce、MIC、RSNE | 站点回应随机数,并验证自己持有 PMK |
| Message 3 | AP → STA | ANonce、MIC、GTK(加密)、RSNE | 确认 PMK 一致,安装 PTK,下发组密钥 |
| Message 4 | STA → AP | MIC | 确认 PTK 安装完成,握手结束 |
2.1 消息 1:AP 的“挑战”
Message 1 由 AP 发出,关键字段包括 Key Descriptor Version、Key Type、Key Replay Counter 和 ANonce。
Key Descriptor Version 有两个值:1 代表 TKIP,2 代表 CCMP。实际抓包里大多看到 2,因为 AES 算法已普及。Key Type 为 0 表示组密钥,为 1 表示成对密钥——4 次握手中这个值固定为 1。
Key Replay Counter 是防重放的重要机制。每次握手时,AP 会给计数器赋一个新值,站点收到消息后会记录这个值。后续消息中的计数器必须与此一致或递增。攻击者无法通过重放旧握手消息来欺骗站点,因为计数器不匹配会被直接丢弃。这个字段在 Wireshark 里显示为 Key Replay Counter。
ANonce 是 AP 生成的 32 字节随机数,用来参与 PTK 计算。这里有一个常被误解的点:ANonce 是明文传输的,因为即使攻击者拿到 ANonce,如果没有 PMK,也推算不出 PTK。随机数本身不保密,但它是密钥派生中的“盐”类输入。
在实际抓包分析时,我习惯用wlan.rsna.anonce过滤器直接筛选携带 ANonce 的帧。如果一条 4 次握手中 AP 的 ANonce 在 Message 1 和 Message 3 里不一致,那基本可以断定中途被干扰或设备驱动有问题。
2.2 消息 2:站点交出“证明”
Message 2 由站点发往 AP,携带 SNonce、RSNE(Robust Security Network Element)和 MIC。
SNonce 是站点生成的随机数,同样明文传输。RSNE 里包含站点支持的加密套件和认证套件——Wireshark 里能直接看到一组套件标识符,多数情况是 CCMP 和 RSNA。MIC 由 KCK 对消息体计算得到,用于让 AP 验证站点的 PMK 是否正确。
MIC 计算的覆盖范围不只是认证字段,还包括消息体中的大部分数据,包括 SNonce、RSNE 和 Key Replay Counter。这意味着攻击者如果在传输途中篡改任何一个字段,MIC 就不匹配,AP 会直接丢弃该消息。这就是“密钥确认”的实际落地。
值得注意的一个细节:Message 2 没有携带 GTK,也没有加密数据。它更像是一次响铃,告诉 AP“我有 PMK 派生的 KCK,愿意继续聊”。如果站点的密码错误,那么它算出的 KCK 与 AP 的 KCK 不同,MIC 校验失败,AP 就不会回应 Message 3。这条线索在排障中非常有用:如果抓包里只有 Message 1 和 Message 2,说明认证失败极大概率是 PSK 不匹配。
2.3 消息 3:AP 确认并下发组密钥
Message 3 是整个握手流程里信息量最大的一条。它包含 ANonce(重复)、MIC、GTK(加密后),以及 GTK 的加密密钥信息。
AP 在收到 Message 2 后会先验证 MIC,然后确认站点确实持有正确 PMK。接着,AP 用 KEK 加密 GTK 并放入 Message 3。KEK 是 PTK 的一部分,所以只有同时拥有 PMK 和握手中的随机数的站点才能解开 GTK。GTK 的加密过程使用 RC4 或 AES,具体取决于 Key Descriptor Version。
Wireshark 中查看 Message 3 时,有一个叫 Key Data 的字段,里面存储的加密数据就是 GTK。如果你配置了 Wireshark 的密钥(即 PMK 或 PSK),它会自动解密 Key Data 显示出 GTK 明文。否则你只能看到一堆密文。常见的情况是:抓包时用wlan_rsna密钥解析,却看不到 GTK,那是因为没有正确导入 PMK,而不是数据损坏。
Message 3 还有一个作用:AP 安装 PTK 并进入加密状态。站点收到 Message 3 并验证 MIC 后,也会安装 PTK,并准备好接收组播/广播帧。此时 4 次握手实际上已经完成了密钥协商,Message 4 只是告知 AP“我已就绪”。
2.4 消息 4:最终确认与状态切换
Message 4 由站点发出,没有新的随机数或密钥材料,只包含 MIC。AP 验证 MIC 后就知道站点已经成功安装 PTK,随后可以放心地在链路上使用加密规则。如果 Message 4 丢失,AP 会收不到确认,从而可能继续重发 Message 3。这也是现场排查时常见的重复握手场景。
需要注意的是,实际抓包中 4 次握手有时并不严格按照 1→2→3→4 出现。由于无线链路的丢包和重传,会出现 Message 1 重传、Message 3 重传,甚至站点主动重发 Message 2 的情况。判断一次握手是否成功,不能只看“有没有四条”,而要看 Key Replay Counter 是否连续,以及最终是否进入加密数据阶段。
3. 组密钥握手:组播密钥的生命周期管理
说完成对密钥,再看组密钥。组密钥握手的参与方同样是 AP 和 STA,但它解决的问题完全不同:PTK 是“一对一”的,而 GTK 是“一对多”的。一个 AP 下的所有站点,必须共享同一把组密钥才能解密广播和组播流量。
3.1 为什么需要单独分发 GTK
802.11 协议中的组播帧和广播帧,接收方不只一个站点。如果每个站点用不同的密钥加密同一份组帧,AP 需要发送多份副本,4 次握手派生的 PTK 对此毫无办法。因此协议规定,AP 额外维护一把 GTK,每个接入的站点在完成 4 次握手后,通过组密钥握手获取这把钥匙。
组密钥握手的本质,是一次带有密钥材料的“通知”——AP 生成新的 GTK,用每个站点自己的 KEK 加密后发送给该站点。站点用 KEK 解密得到 GTK,并安装到硬件加密引擎中。
GTK 需要定期更新以保证前向安全。如果某个站点被踢出网络,或者 AP 检测到疑似密钥泄露,AP 会立即更新 GTK。如果 GTK 长期不变,被踢出的站点依然能解密后续的组播流量,这是不可接受的。企业网络通常将 GTK 更新周期配置在 600 秒左右,家用路由器多为 86400 秒甚至不主动更新。
3.2 组密钥握手的两种消息:GKM 和 WPA 组数据
组密钥握手实际上由两条消息构成:
- 第 1 条:AP → STA,携带 Key Descriptor Version、GTK(加密)、Key Replay Counter 和 MIC。
- 第 2 条:STA → AP,携带空的 MIC 确认,通知 AP 已成功安装 GTK。
如果站点没有正确解密 GTK,或者 MIC 校验失败,站点会发送一个 WPA 错误帧(历史上用 2 号消息中的状态码表示),AP 将重传组密钥握手。
在 Wireshark 里,组密钥握手帧的类型仍然是 EAPOL,但 Key Type 字段通常为 0(组密钥)。如果筛选eapol,可以看到这些帧与 4 次握手混在一起,新手容易搞混。区分方法是看 Key Type 和消息序号:4 次握手是成对密钥(Key Type=1),组密钥握手是组密钥(Key Type=0)。
3.3 重传与超时对组密钥的影响
组密钥握手的可靠性依赖于重传机制。AP 发出第一条组密钥消息后,如果没有在规定时间内收到确认,就会重传。重传次数耗尽后,AP 可能会认为站点失联并强制断开。
实际运维中常见的现象是:站点在漫游切换后,组密钥握手的消息序号与 AP 当前的 Key Replay Counter 不一致,导致握手失败。这时候无论怎么重试都连接不上,重启无线网卡驱动即可解决。这个现象在大量使用快速漫游(如 802.11r)的园区网络中尤为明显,排查时不要只盯 RSSI,要去看 EAPOL 消息序列。
这里分享一个我的实操经验:在某园区无线网络压力测试中,大约 200 个并发终端同时关联 AP,经常出现部分终端收不到组密钥第一条消息的情况。查了日志发现是 AP 的组密钥重传队列溢出,后来调整了组密钥更新周期并启用了多播增强调度,问题基本消失。所以遇到“部分终端能上网但收不到组播”的情况,优先怀疑组密钥握手超时,而不是交换机和 AP 配置。
4. 实操:用 Wireshark 一步步捕获和分析 EAPOL 握手
很多人觉得抓无线包很麻烦,其实只要有支持监听模式的网卡,配合正确的设置,几分钟就能完成一次高质量的握手采集。下面以 Wireshark 为主线,讲一下最常用的分析流程。
4.1 环境准备与抓包参数
先确认网卡支持监听模式。Windows 下可以买一块常见芯片的 USB 无线网卡;Linux 下直接用ip link set wlan0 up开启。抓包前建议把网卡固定到目标 AP 所在的信道,否则很多帧会被跳过。
Wireshark 捕获过滤器建议设置为:
wlan.fc.type_subtype == 0x00 || wlan.fc.type_subtype == 0x08 || eapol其中0x00是关联请求帧,0x08是信标帧,eapol用于过滤 EAPOL 帧。关联帧和信标帧帮助我们确认目标 AP 的 BSSID 和信道,EAPOL 帧则是握手的核心。
抓完包后,用显示过滤器eapol查看所有 EAPOL 消息。如果只想看 4 次握手,可以用wlan.rsna.eapol或者wlan.fc.type_subtype == 0x08配合eapol。我自己习惯右键任意一个 EAPOL 帧,选择“Conversation Filter → Ethernet”来隔离单条握手的全部消息。
4.2 还原密钥并进行解密
要解密后续的数据帧,必须让 Wireshark 知道 PMK。两种方式:
第一种,个人网络下直接输入 PSK。打开 Wireshark 的“编辑 → 首选项 → Protocol → IEEE 802.11 → Decryption Keys”,添加一条密钥,类型选wpa-pwd,格式是密码:SSID。例如密码TestPass123、SSIDDemoWiFi,填入TestPass123:DemoWiFi。Wireshark 会根据这个 PSK 自动派生 PMK,再通过握手中的随机数派生 PTK。
第二种,企业网络下需要先提取 PMK,或者用抓包工具在 802.1X 过程后导出密钥,再以wpa-psk类型导入。
解密成功后,802.11 数据帧会显示为可读的部分,Web、DNS、ARP 等协议都能正常解析。如果出现部分帧能解密、部分帧解密失败,多数情况下是 GTK 更新期间的部分帧没有抓到,或者是 AP 已开始使用新的 GTK 但 Wireshark 只拿到了旧密钥。
4.3 从握手帧中提取关键参数
用 tshark 可以快速提取握手中的关键字段,我把常用的命令贴在下面:
tshark -r capture.pcapng -Y "eapol" -T fields \ -e frame.number \ -e wlan.sa \ -e wlan.da \ -e eapol.keydes.keytype \ -e eapol.keydes.keyinfo \ -e wlan.rsna.anonce \ -e wlan.rsna.snonce输出结果里能清楚看到每条 EAPOL 的源地址、目的地址、密钥类型、随机数。对比 Message 1 和 Message 3 的 ANonce,Message 2 和 Message 4 的来源,基本能拼接出完整的协商过程。
如果需要验证某个密钥派生的正确性,可以借助离线计算工具。把 ANonce、SNonce、双方 MAC 地址、PMK 一起输入,计算得到的 PTK 与 Wireshark 自动派生的结果进行对比。如果一致,说明抓包链路没有中间人篡改;如果不一致,检查是工具输入顺序错误还是抓包时存在帧偏移。
4.4 分析一次完整握手的步骤清单
根据我在现场排查的经验,一次完整的握手分析可以参考以下步骤:
- 打开 pcap,筛选
eapol,找到待分析的一组握手帧。 - 依次检查四条消息的 Key Replay Counter,是否逐次递增。
- 检查 Message 1 和 Message 3 中的 ANonce 是否一致。
- 检查 Message 2 和 Message 4 双方 MAC 地址是否符合预期。
- 导入 PSK 或 PMK,验证数据帧能否解密。
- 查看握手完成后的第一条数据帧,确认它使用的是 CCMP 加密且 Wireshark 能显示明文。
- 如果失败,重点排查 MIC 校验错误和 Key Replay Counter 冲突。
这套流程用到烂熟,基本能应对九成以上的无线连接故障和安全分析场景。
5. 常见问题与排查技巧实录
理论和实操都讲完,最后把我在实际工作中反复遇到的坑集中整理一下。这些问题在官方文档里大多“说了但没说透”,只有踩过坑才能体会到哪句话真正重要。
5.1 只有 Message 1 和 Message 2,没有后续消息
这个场景我在客户现场遇到不止十次。现象是终端能关联上 AP,但一直处于“获取 IP 地址”的转圈状态,抓包只有两条 EAPOL。
排查思路:先确认 PSK 是否正确。检查 AP 的日志或者用另一台设备测试相同的密码。如果密码无误,再检查是不是站点的无线驱动开启了 PMF(管理帧保护)而 AP 没有开启,导致握手中的 RSNE 能力协商不一致。在 Wireshark 中确认 RSNE 里的 AKM 套件(Authentication Key Management Suite):如果是 PSK,应该显示 00-0f-ac-02;如果是企业级 802.1X,显示 00-0f-ac-01。套件不一致也会导致只到 Message 2 就失败。
5.2 重传风暴:反复出现 Message 1 和 Message 3
如果在抓包里看到同一对 MAC 地址之间反复出现 Message 1 或者 Message 3,通常意味着对端没有确认。举例来说,AP 重发 Message 3,说明站点没有正确回应 Message 4;站点重发 Message 2,说明 AP 没有正确回应 Message 3。
这类问题最常见的原因是无线信号质量问题。但还有一个隐蔽因素:AP 的 802.11n/ac 发射模式与站点的省电模式配合不好,导致 EAPOL 帧被 AP 缓存而没有及时投递。关闭站点的省电模式,或者把 AP 的基础速率调低,往往能立竿见影。
5.3 数据帧能解一半,组播全乱码
这种情况几乎都是 GTK 相关。Wireshark 里数据帧部分能解、部分不能解,说明单播会话密钥(PTK)正常工作,但组播数据帧使用的 GTK 未被成功解密。原因可能是:
- 你只导入了 PMK,没有让 Wireshark 从组密钥握手里提取 GTK;
- 组密钥握手发生在抓包时间窗口之外;
- AP 更新 GTK 后,后续数据帧使用新 GTK 而抓包工具未同步。
解决方案:确保在 Wireshark 中打开“Enable decryption”,并且不要过早停止抓包,等组密钥握手完成后再分析。如果你是在一次完整测试中抓包,应当能看到组密钥握手两条消息,再利用“View → Wireless → WLAN Statistics”检查 GTK 的更新历史。
5.4 PMKID 攻击:为什么它绕开了 4 次握手
现在市面上很多 Wi-Fi 安全工具已经不再依赖完整的 4 次握手来破解 PSK,而是直接抓 PMKID。PMKID 是 RSNE 里的一个扩展字段,在 AP 发送 Message 1 时(甚至不关联的情况下)就会出现在信标或探测响应里。攻击者拿到 PMKID 后,结合 SSID 和 AP 的 MAC 地址,离线跑字典即可验证 PMK 是否正确。
这意味着即使站点和 AP 之间完全没有成功握过手,攻击者也能开始字典攻击。很多人奇怪“我不上网为什么密码还能被破解”,答案就在这里。防护手段只有一条:使用足够随机、足够长的 PSK。一个 20 位的随机字符串,暴力破解的尝试空间已经是天文数字。
我见过不少案例,安全测试时对同一 SSID 做 PMKID 攻击,目标密码是 “admin2023” 这类弱口令,几乎秒破;而另一组使用 16 位大小写数字混合密码,跑了几个 GPU 节点一周也没出结果。无线安全里最薄弱的环节永远是口令强度,而不是协议本身。
5.5 密钥重装攻击(KRACK)给我们的启示
研究 4 次握手绕不开 2017 年披露的 KRACK 攻击。它的本质是:当 Message 3 重传时,站点会重新安装已经存在的 PTK 和 GTK,密钥安装的“重装”行为导致密钥流重用。攻击者在中间做干扰,迫使 AP 重传 Message 3,进而重放加密数据。
这件事给无线协议分析留下了一个很重要的提醒:即使 4 次握手在协议设计上是安全的,具体实现的驱动和固件也可能在状态管理上出漏洞。做安全分析时,不能只盯着帧格式,还要关注设备对“重传”和“重装”的状态处理。好在当时的漏洞披露后,主流系统都打了补丁,现在抓包时已很难再复现。
就我个人经验而言,802.11i 的复杂性不在于算法本身,而在于协议状态机中细节与细节之间的相互影响。如果你能把 4 次握手每一步的状态变化、每个字段对端会如何响应都梳理清楚,那么排查无线安全问题时会比绝大多数人快很多。最后再分享一个小技巧:抓包时顺手开启信标帧统计,观察同一 BSSID 的信标序列号是否连续。如果信标有丢失,后续 EAPOL 帧超时重传的概率会显著增大——这往往是信道拥堵最早期的信号,等到抓包看到重传风暴时,问题通常已经存在很久了。