WPA2加密
WPA2的分类
WPA2(Wi-Fi Protected Access 2安全协议)分为两种:
WPA2-PSK:基于预共享密钥(PSK)的个人模式
WPA2-Enterprise:基于 802.1X 认证的企业模式
WPA2的加密算法
WPA2加密算法分为两类:
CCMP:基于AES的对称加密技术;AES支持128、192和256位密钥长度。
TKIP:基于RC4加密算法,注意:TKIP用于替代 WEP(Wired Equivalent Privacy)中的不安全加密机制。虽然 TKIP 也适用于 WPA2,但由于其安全性较低,已经逐渐被 AES 替代。

WPA2-PSK个人模式
4步握手过程如下图所示:

过程分析:
PMK:成对主密钥 256bit 作用:密钥树根,永不传输 sta和ap自己各一份
生成方式:PMK=PBKDF2(HMAC-SHA1,WIFI密码,ssid, len(ssid),4096,256)
参数说明:
HMAC-SHA1:哈希函数
WIFI密码:sta和ap一样
WIFI ssid:sta和ap也一样,就是wifi的名字
len(ssid):名字长度
4096:该函数的迭代次数,多次迭代主要为了防暴力破解
256:输出长度
PTK:成对临时密钥 512bit 作用:单 STA-AP 会话加密,含 KCK/TK/KEK/MIC key,下面是PTK的组成:
字段
长度
在 PTK 中的字节范围
核心作用
KCK
16 字节
0 ~ 15 字节
计算 / 验证握手帧的 MIC
KEK
16 字节
16 ~ 31 字节
加密 / 解密 GTK
TK
16 字节
32 ~ 47 字节
AES-CCMP 数据传输的核心密钥
MIC Key
16 字节
48 ~ 63 字节
备用 MIC 校验(兼容旧设备)
PTK生成方式如下:
PTK= SHA1_PRF(PMK,len(PMK), Pairwise key expansion, Min(AA,SA)||Max(AA,SA)||Min(ANone,SNonce)||Max(ANone,SNonce))参数说明:
PMK:STA自己生成的自己的PMK
Pairwise key expansion:WPA2-802.11i标准强制规定的固定字符串本质是SHA1_PRF盐(Salt)
AA:AP的mac地址
SA:STA的mac地址
SNonce:sta自己生成的随机数
ANone:AP发过来的随机数
MIC计算方式如下:
MIC=HMAC_MD5(KCK,16,802.1Xdata)[0到16字节]
此时ap收到了sta的SNonce 所以 ap同样可以计算自己的PTK和MIC,计算方式和sta一致,然后ap把收到sta的MIC和自己的MIC进行完整性校验,如果校验失败,握手失败,否则就成功,继续往下生成GTK,注意:这个过程会生成ap自己的PTK,所以里面有个KCK和KEK,后面生成GTK要用。
GTK前20字节格式如下:
字段名
字节长度
取值 / 说明
GTK 版本号
1字节
固定为0x02(标识 WPA2-CCMP 类型的 GTK,区分 WPA1/TKIP 的 GTK
GTK 核心随机数
15字节
从/dev/urandom读取的真随机数(加密核心,永不明文传输)
PN(包序列号)
4字节
初始包序列号(Packet Number),用于 CCMP 计数器生成,防重放攻击,从0x00000001自增
GTK 生成的步骤如下:
读取该bssid下的GTK缓存检查有效期,若过期则重新生成GTK的前20字节,否则直接复用;
读取得到的GTK的前16字节(版本+随机数),生成12字节随机的Nonce(用于aes-ccmp加密);
调用aes-ccmp加密算法,生成加密的GTK
Encrypted GTK = AES-CCMP(KEK,上面生成的Nonce,上面提到的前16字节GTK)
最终传输加密GTK数据=12字节的Nonce+26字节Encrypted_GTK+8字节的TAG 一共36字节
构造第三次握手包Message3
Step 1: 构造空的第三次握手EAPOL-Key帧,填充核心字段:
Key Descriptor Type:0x02(WPA2-PSK);
Key Information:标记Unicast+CCMP;
Key Length:0x0080(128位)
Replay Counter:AP生成的8字节计数器(如
00 00 00 00 00 00 00 01);ANonce:AP第一次握手发送的32字节随机数;
Key RSC:GTK的4字节PN(如
00 00 00 01);MIC字段:先填充16字节全0;
Key Data:36字节加密GTK数据(Nonce+Encrypted_GTK+Tag);
Key Data Length:0x0024(36字节);
Step 2: 调用HMAC-SHA1计算AP的MIC:
AP_MIC = HMAC-SHA1(KCK, 16, 填充0的EAPOL帧, 帧长度) [0:16];
Step 3: 将AP_MIC替换帧中的MIC占位符,完成帧构造。
STA收到Message3后动作分析
6.1 解析消息
驱动层过滤 EAPOL-Key 帧(以太网类型 0x888E),转发给用户态的 wpa_supplicant;
解析帧的核心字段并存储(与 AP 构造的字段一一对应):
AA:AP 的 MAC 地址(确认是目标 AP);
AP_MIC:AP 计算的 16 字节 MIC 值;
Encrypted_GTK_Data:36 字节加密 GTK 数据(12 字节 Nonce + 16 字节加密 GTK + 8 字节 Tag);
PN(Key RSC):4 字节 GTK 包序列号(防重放);
ANonce:AP 的随机数(校验与第一次握手的 ANonce 一致);
Replay Counter:AP 的 8 字节防重放计数器;
Key Information:确认是 Unicast/Pairwise、CCMP 加密;
校验帧结构合法性(字段长度、版本号),非法则直接丢弃。
6.2 重放攻击检测(前置安全校验)
wpa_supplicant 查询本地缓存的 “AP-Replay Counter 映射表”(记录该 AP 的最新计数器值);
对比当前帧的 Replay Counter 与缓存值:
若当前值 ≤ 缓存值 → 判定为重放帧,发送 Deauth 帧给 AP,终止握手;
若当前值 > 缓存值 → 更新缓存值,进入下一步;
校验 ANonce 一致性:对比当前帧的 ANonce 与第一次握手接收的 ANonce,不一致则丢弃帧(防止 ANonce 被篡改)。
6.3 验证 AP 的 MIC(核心:确认 AP 拥有合法 PMK/PTK)
从本地已计算的 PTK 中提取 KCK(前 16 字节,与 AP 侧 KCK 完全一致);
构造 “待校验的 EAPOL 字节流”:
复制第三次握手帧的所有核心字段;
将帧中的 AP_MIC 字段替换为 16 字节全 0(与 AP 计算 MIC 时的占位逻辑一致);
调用 HMAC-SHA1 计算校验 MIC:STA_CALC_MIC = HMAC-SHA1 (KCK, 16, 填充 0 的 EAPOL 帧,帧长度) [0:16];
对比 STA_CALC_MIC 与 AP_MIC:
不一致 → MIC 校验失败,发送 Deauth 帧(原因码 4),终止握手;
一致 → 确认 AP 拥有正确 PMK/PTK,进入 GTK 解密阶段。
6.4 解密 GTK(核心:提取合法的组密钥)
从本地 PTK 中提取 KEK(密钥加密密钥):KEK = PTK [16:32](16 字节);
拆分 36 字节 Encrypted_GTK_Data:
12 字节 Nonce(AES-CCM 加密的随机数);
16 字节 Encrypted_GTK(加密后的 GTK 核心:版本 + 随机数);
8 字节 Tag(认证标签,防篡改);
调用 AES-CCM 算法解密:Decrypted_GTK_Core = AES-CCM (KEK, Nonce, Encrypted_GTK, Tag);(解密时会校验 Tag,Tag 不匹配则判定 GTK 被篡改,终止握手);
拼接完整 GTK:将解密后的 16 字节核心 GTK(版本 + 随机数)与帧中提取的 4 字节 PN 拼接,形成 20 字节完整 GTK(与 AP 侧格式一致):完整 GTK = 1 字节版本号 + 15 字节随机数 + 4 字节 PN。
6.5 GTK 格式校验(确保符合 WPA2 标准)
校验版本号:解密后的 GTK 核心首字节必须为
0x02(WPA2-CCMP 标识),否则丢弃;校验长度:解密后的核心 GTK 必须为 16 字节,完整 GTK 为 20 字节,长度错误则丢弃;
校验 PN 有效性:PN 必须为非 0 值(如
0x00000001),全 0 则判定为非法 GTK;本地存储完整 GTK,标记为 “待安装”。
6.6 安装密钥(PTK/TK + GTK)到驱动层
从 PTK 中提取 TK(传输密钥):TK = PTK [32:48](16 字节);
向驱动下发密钥安装指令:
安装 TK:关联到 AP 的 MAC 地址,用于单播数据的 AES-CCMP 加密;
安装 GTK:关联到当前 BSSID,用于广播 / 组播数据的 AES-CCMP 加密;
配置 PN:将 GTK 的 PN 设置为 CCMP 计数器初始值(防重放);
驱动层启用 AES-CCMP 加密 / 解密逻辑,标记该 AP 连接为 “加密就绪”;
wpa_supplicant 标记 STA 状态为 “密钥安装完成,待确认”。
6.7 构造并发送第四次握手 ACK 帧(最终确认)
构造空的第四次握手 EAPOL-Key 帧,核心填充:
Key Information:标记 “ACK 确认”“密钥已安装”;
Replay Counter:复用 AP 第三次握手的 Replay Counter(防重放);
MIC 字段:填充 16 字节全 0(第四次握手无需新 MIC,仅作确认);
其他字段:Key Descriptor Type=0x02,Key Length=0x0080;
wpa_supplicant 将帧下发给驱动;
驱动以 Unicast 方式(目标 MAC=AP 的 MAC)发送该帧;
启动超时定时器(QSDK 默认 5 秒),若未收到 AP 确认则重发(最多 2 次)。
6.8 启动正常加密数据传输
第四次握手帧发送成功后,STA 标记与 AP 的连接为 “已认证 + 已关联 + 加密就绪”;
驱动层对所有上行数据(STA→AP)执行 AES-CCMP 加密:
用 TK 生成 CCMP 计数器(结合 PN / 数据包序列号);
加密数据并附加 CBC-MAC 校验值;
驱动层对所有下行数据(AP→STA)执行 AES-CCMP 解密 + 校验:
先校验 CBC-MAC,确保数据未被篡改;
解密数据,若 PN 重复则丢弃(防重放);
进入正常数据传输阶段,所有流量均为加密状态。
ap收到Messsage4后的动作
7.1 接收并解析第四次握手帧
驱动层过滤 EAPOL-Key 帧(以太网类型 0x888E),确认帧的目标 MAC 是 AP 自身 MAC(Unicast 帧),转发给 hostapd;
hostapd 解析帧的核心字段,仅关注关键标识(第四次握手帧无新 MIC/GTK,仅作确认):
SA:STA 的 MAC 地址(定位是哪个 STA 的确认帧);
Key Information:提取 “ACK 确认” 标志(bit 9 置 1)、“密钥已安装” 标志(bit 8 置 1);
Replay Counter:STA 复用的 AP 第三次握手的 8 字节计数器(核心防重放参数);
MIC 字段:确认是 16 字节全 0(第四次握手标准要求,非 0 则判定为非法帧);
校验帧结构合法性:字段长度、版本号(Key Descriptor Type=0x02),非法则直接丢弃。
7.2 重放攻击检测(核心前置校验)
从本地 “STA-Replay Counter 缓存表” 中,读取该 STA 对应的第三次握手 Replay Counter 值;
对比当前帧的 Replay Counter 与缓存值:
若当前值 ≠ 缓存值 → 判定为重放帧 / 篡改帧,丢弃,不更新状态;
若当前值 = 缓存值 → 确认是合法的 ACK 帧,进入下一步;
标记该 Replay Counter 为 “已确认”,避免后续重复处理。
7.3 STA 握手状态校验(确保流程匹配)
查询本地 “STA 握手状态表”,读取该 STA 的当前状态:
合法状态:“已发送 Message3,等待 Message4 确认”;
非法状态:“未握手”“已完成握手”“MIC 校验失败” 等;
状态校验:
若状态不匹配 → 丢弃帧,标记该 STA 为 “异常”,超时后清理;
若状态匹配 → 确认是该 STA 的合法 ACK,进入密钥安装阶段;
重置 Message3 重发定时器(若之前启动过),避免重复发送 Message3。
7.4 安装密钥(PTK/TK + GTK)到驱动层
从本地缓存中读取该 STA 对应的 PTK(64 字节),提取关键子密钥:
TK(传输密钥):PTK [32:48](16 字节),用于单播数据加密;
KEK/KCK:已完成握手验证,无需再使用,标记为 “待清理”;
向高通 Wi-Fi 驱动下发密钥安装指令(QSDK 通过 nl80211 接口实现):
安装 TK:关联到 STA 的 MAC 地址,用于 AP→STA 单播数据的 AES-CCMP 加密;
安装 GTK:关联到当前 BSSID(该 STA 已接入的热点),用于广播 / 组播数据加密;
配置 PN:将 GTK 的 4 字节 PN 设置为 CCMP 计数器初始值(防重放攻击);
驱动层启用 AES-CCMP 加密 / 解密逻辑:
上行(STA→AP):解密数据前先校验 CBC-MAC,PN 重复则丢弃;
下行(AP→STA):加密数据并附加 CBC-MAC,PN 自增;
驱动返回 “密钥安装成功” 确认给 hostapd。
7.5 清理握手临时缓存(安全优化)
从内存中删除该 STA 对应的临时数据:
PMK(仅保留哈希值,原始 PMK 清零);
PTK、KCK、KEK(字节数组填充 0 后释放);
ANonce、SNonce(随机数清零);
握手过程中的 EAPOL 帧缓存;
清理 “STA-Replay Counter 缓存表” 中该 STA 的临时计数器;
释放握手过程中占用的 crypto API 资源(如 HMAC-SHA1/AES-CCM 上下文)。
7.6 标记连接状态 + 启动正常加密传输
hostapd 更新该 STA 的状态为:
认证状态:“802.1X 认证完成”(WPA2-PSK 模拟 802.1X);
关联状态:“已关联”;
加密状态:“AES-CCMP 已启用”;
将该 STA 加入 “已接入设备列表”,可通过
hostapd_cli sta命令查看;驱动层开始对该 STA 的所有数据帧执行 AES-CCMP 加密 / 解密:
下行数据(AP→STA):用 TK 加密单播帧,用 GTK 加密广播 / 组播帧;
上行数据(STA→AP):解密后校验完整性,异常则丢弃并记录日志;
QSDK 的
wlan进程标记该连接为 “活跃”,纳入流量统计。
7.7 GTK 定时更新 + 异常处理
启动 GTK 定时更新定时器(QSDK 默认 3600 秒 / 1 小时):
到期后 AP 生成新 GTK,通过 Multicast EAPOL-Key 帧分发给所有已接入 STA;
新 GTK 生成后,旧 GTK 保留 10 秒(兼容 STA 切换),之后清零;
异常超时处理:
若未收到 Message4,AP 会重发 Message3(最多 3 次,QSDK 默认 10 秒超时);
重发失败则标记该 STA 为 “握手失败”,发送 Deauth 帧(原因码 15,4-Way Handshake timeout);
日志记录:在
/var/log/hostapd.log中记录 “4-Way Handshake completed for STA [MAC]”,便于调试。
整体说明如下:


WPA2-Enterprise 企业模式
