☰
WPA2-PSK口令强度自查:四次握手抓包与离线字典校验
2026/11/2 11:37:36 网站建设 项目流程

简介:这份资料围绕无线网络密码安全展开,定位为面向具备基础计算机网络知识、希望了解Wi-Fi认证机制与常见风险的读者,内容将教程与配套软件打包在一起,便于在合法授权范围内做安全自查与学习。资源以rar压缩包分发,大小约3.33MB,文件总数及具体类型明细上游暂未提供,从描述看以图文教程和工具软件为主,可作为无线安全入门参考资料,帮助读者建立对无线认证与口令安全的基本认识。页面显示已有6996人学习或下载,说明该主题关注度较高。读者可从中了解无线密码泄露的常见成因、口令强度的重要性以及基础排查思路,但需注意:未经授权破解他人Wi-Fi属于违法行为,务必仅用于自有网络或取得书面授权的安全测试,切勿将相关方法用于侵犯他人网络权益。

1. 从“隔壁的密码”到“自己的靶场”:先把方向掰正

搜「破解 Wifi密码」这个词进来的人,想解决的多半是同一件事:连不上、想省点宽带、或者纯粹好奇。我先把话说明白:这篇不写怎么进别人家,写的是把测试目标换成自己管的网络,做一次完整的口令强度自查:自己搭靶场、自己抓握手、自己造字典、自己核算耗时,最后反推加固方案。这条链路我前后跑了十几轮,失败记录全留着。

三类人能直接用:手里管着几十上百个 AP 的运维,想知道自家口令到底扛不扛得住;刚入门、没弄明白握手包到底是什么的新手;还有被“抓个包就能出密码”这句话忽悠过、试到凌晨三点的人。下面每个参数都在模拟项目X上实跑过,失败原因也一并写进去。

2. 靶场怎么搭:一台旧路由加一条隔离网段就够

动手之前先把“能做的事”和“不能做的事”分清楚。这不是客套话,我见过太多人环境没搭明白就急着抓包,折腾一晚上连一个 EAPOL 帧都没拿到,最后怀疑网卡坏了。实际上九成问题出在环境配置上,跟工具本身没关系。

2.1 三条线先划:授权、隔离、留痕

我会在动手前把这三条写进一个文本文件里,不为了给别人看,为了给自己看:

  1. 授权边界:只有自己名下、或者有书面授权的设备才进靶场。租的房子、合租的宽带、公司网络,都不算“自己的”;
  2. 网络隔离:靶场 AP 用独立 SSID、独立网段,不接办公网、不接生产网,最好干脆不接外网,避免校验过程里产生意料之外的流量;
  3. 过程留痕:日期、设备 MAC、目的、参与人,一行一条记下来。

第三条最容易被跳过,但它是出事之后唯一能说清楚的东西。我一般会在《模拟项目X》目录下建一个scope.md,把这三条写死在开头,后面所有数据都存同一个目录,时间一长回头看也不至于记混。

2.2 模拟项目X的硬件清单与关键配置

这套环境不需要添置任何新东西,退役设备凑一凑就够。

角色设备关键配置
目标 AP退役家用路由一台SSIDLAB-SELFTEST,WPA2-PSK / CCMP,2.4G 固定信道 6,关闭 WPS
客户端旧手机一台连上后保持待机,别让它自动断连
抓包端支持监听模式的无线网卡固定信道 6,监听模式,单独接口
校验端带独显的主机一台全程离线,不联网

四个选择各有理由,不是随手定的:

为什么选 WPA2-PSK 而不是 WPA3-SAE:这是整个方案的前提。WPA3 的 SAE 握手用的是另一种推演方式,双方交换的是从口令派生出来的中间值,抓到的帧里没有能直接拿去做离线校验的材料。也就是说,对着 SAE 跑字典,方向从一开始就是错的,只在协议层面就被堵死了。我见过有人拿着 WPA3 的抓包文件跑了两天,最后发现根本不存在能校验的字段。所以靶场这一层,老老实实用 WPA2-PSK,先把链路跑通,再讨论协议演进带来的差异。

为什么固定 2.4G 的信道 6:5G 频段信道多、跳频空间大,监听网卡如果不锁信道,很容易在跳转的间隙漏掉关键帧。2.4G 只有 1、6、11 三个互不重叠的信道,锁死一个,漏帧概率最低。这个细节看着小,实际决定了你今晚能不能收工。

为什么关掉 WPS:WPS 的 PIN 校验是另一条独立路径,跟四次握手不在一个维度上。两个东西混在一起测,出了问题根本分不清是哪条链路的问题。先把变量控制住,一次只验证一件事。

为什么校验端要离线:字典校验是纯本地计算,不需要任何网络交互。离线跑既快又干净,也不会把测试流量和生产流量搅在一起。

2.3 把监听接口配起来

环境搭好之后,第一件事是确认网卡到底支不支持监听模式。这一步别猜,直接查。

# 1) 查网卡支持的接口模式,输出里必须出现 monitor iw list | grep -A 6 "Supported interface modes" # 2) 切监听模式前必须先 down,否则 set type 会报 device busy sudo ip link set wlan1 down sudo iw dev wlan1 set type monitor sudo ip link set wlan1 up # 3) 把监听口锁到 AP 所在信道,不要让它自动跳 sudo iw dev wlan1 set channel 6 # 4) 复核:type 必须是 monitor,channel 必须是 6 iw dev wlan1 info

四个步骤里,第 1 步是判断条件是否满足,第 2 步是顺序问题,第 3 步是精度问题,第 4 步是唯一可信的复核点。

  • 第 1 步输出里没有monitor字样,说明网卡或驱动不支持,换硬件,别在软件层折腾;
  • 第 2 步的down不能省,接口处于 up 状态时改类型一定失败;
  • 第 3 步的信道要按 AP 实际信道改。AP 在 11 你就写 11,写错了抓一晚上全是隔壁 AP 的信标帧;
  • 第 4 步别信任何工具界面上显示的“已监听”,只信iw dev info的输出。

提示:监听接口一旦 up 起来就会持续收帧,长时间挂着会占满磁盘。抓包文件按 50MB 一个切分,方便反复回放,也不至于把盘写满。

2.4 先跑一遍“完全正常”的连接

正式抓包之前,让客户端正常连一次靶场 AP,确认这次连接是完整的:能拿到地址、能保持在线、不会连上三秒就掉。

这一步的意义在于建立基线。后面所有分析都建立在“这次连接本身没问题”的假设上,如果基线就是坏的,你永远分不清是抓包环节漏了帧,还是客户端压根没连稳。我会在这一步顺手看一眼信标帧的发送间隔和 SSID 字段,确认监听口收到的确实是这个 AP 的帧,而不是同名 SSID 的另一个设备。同名 SSID 在密集住宅区非常常见,认错目标是最冤枉的一种失败。

3. 握手包从哪来:把四次握手拆到字段级

环境跑通之后,核心问题就一个:那个能拿去离线校验的东西,到底是什么。不理解这一层,后面造字典、算耗时全是盲猜。

3.1 四次握手里到底交换了什么

客户端和 AP 建立加密连接时会走一次四次握手。整个过程里有几个量值得盯住:

  • PMK(成对主密钥)= 用口令、SSID 和固定迭代次数派生出来的值;
  • ANonce / SNonce:AP 和客户端各自生成的随机数,明文传输;
  • PTK(成对临时密钥):由 PMK、两个 Nonce 和双方的 MAC 地址推出来;
  • MIC:用 PTK 里的一段对消息做的完整性校验值。

把这几个量摆在一起,结论就很清楚了:抓包端能拿到两个 Nonce、双方的 MAC、SSID 以及 MIC,唯一不知道的是 PMK,而 PMK 只由口令和 SSID 决定。所以“离线校验”的本质是——把字典里的每个候选口令代进去算一遍 PMK,再推 PTK,再算 MIC,跟抓到的 MIC 比对。对上了,口令就是它。全程不需要再和 AP 通信一次。

这里有个特别容易忽略的点:SSID 是盐。口令相同、SSID 不同,算出来的 PMK 完全不同。这意味着改一次 SSID,之前所有跑出来的结果全部作废,字典也得重新绑定。这个坑我在早期项目里踩过一次,改完 SSID 还在用旧结果,对着一个“明明有”的字典跑到天亮。

3.2 让握手重来一次:被动等和主动触发

握手不是随时都在发生的,它只在客户端连上 AP 的那一刻出现。所以采集手段只有两种:

被动等待:抓包端挂在信道 6 上不动,等客户端自己重连。优点是零干扰,缺点是不可控——客户端可能一整天都不重连,你只能干等。

主动触发:让 AP 主动断开一下客户端,逼它重新走一次握手。这是靶场里的标准做法,因为靶场里的设备全是你自己的,踢了也无所谓。但同一个动作作用在别人的网络上,性质完全不同,它构成对他人网络的干扰。这条线必须刻在脑子里,别在别人的环境里“顺手试一下”。

采集的时候让抓包进程把监听口上的原始帧落盘,只留管理帧和密钥协商帧,控制单文件大小。落盘之后不要急着重跑,先判断手里这份数据到底全不全。

3.3 自己写个解析器:先确认“抓全了没有”

很多人的做法是抓到文件直接丢进校验流程,跑不出结果再回头怀疑字典。更快的路径是先解析一遍帧,确认四条消息里到底收到了哪几条。

import struct def parse_eapol(raw: bytes) -> dict: """从原始以太网帧中切出密钥协商帧的关键字段。 raw: 一整帧原始字节,前 14 字节是以太网头 返回: 关键字段字典;不是密钥协商帧则返回空字典 """ eapol = raw[14:] if len(eapol) < 4: return {} version, ptype, length = struct.unpack("!BBH", eapol[:4]) if ptype != 3: # 3 表示这是密钥协商帧 return {} key = eapol[4:4 + length] desc = key[0] # 密钥描述符类型 key_info = struct.unpack("!H", key[1:3])[0] # 标志位,判断消息序号 replay = struct.unpack("!Q", key[5:13])[0] # 重放计数,判断是否同一轮 return { "desc": desc, "key_info": key_info, "replay": replay, "has_mic": bool(key_info & 0x0100), # 是否携带完整性校验 "is_pairwise": bool(key_info & 0x0008), # 是否成对密钥消息 }

这段代码只做一件事:把一帧原始字节切成可判断的字段,不涉及任何口令计算。

  • raw[14:]是跳过以太网头,直接定位到协议头;
  • ptype != 3是过滤,密钥协商帧之外的东西全部丢弃,包括大量信标帧;
  • replay是最有用的字段,同一轮握手里的几条消息这个值单调递增,用它可以把散落在几万帧里的四条消息归到一组;
  • has_mic用来区分方向:带 MIC 的是客户端发出去的,不带的是 AP 发的;
  • is_pairwise用来排除组密钥消息,那些对校验没用。

把解析结果按replay分组,你就能得到一份清晰的清单:这一轮收到了消息 1 和 2,那一轮只收到 3 和 4。能拿去校验的最低要求是:至少有消息 2 或消息 4 里的一个,并且有对应的消息 1 提供 Nonce。只有消息 1 或者只有消息 3 的数据,看着像抓到了,其实完全用不了。

4. 口令强度怎么量:字典、规则与离线校验的耗时账

手里有了一份完整的握手数据,接下来的问题变成:怎么用最小的代价,量出自己这个口令到底有多强。

4.1 字典要按“人的偷懒习惯”造,不是按字母表造

真实场景里命中率最高的字典,从来不是最大的那个,而是最贴合“这个网络的主人”的那个。做自查的时候要故意按自己起密码的习惯来造,否则测出来的强度是虚高的。常见的几类模式:

模式生成规则量级
SSID 变形原样、大小写变体、加年份、加常见后缀百级
手机号常见号段前缀 + 后 8 位十亿级
生日年份 + 月日,含常见分隔写法十万级
键盘序相邻键位串 + 数字后缀万级
拼音 + 数字常见词表 + 4 位数字后缀百万级
纯数字6 到 10 位全铺十亿级

这张表的用法是:先挑三到五类最像自己的,拼一个小字典跑一遍。如果一轮就命中了,说明这个口令在现实里基本等于没有,后面的就不用测了,直接去改。

4.2 生成器的写法:边算边落盘

字典一上规模,最容易出的问题不是算得慢,是内存先炸。写法上要避免“先攒全集再排序”这种思路。

import itertools def gen_candidates(ssid: str, out_path: str): """按常见起密码习惯生成候选口令,边生成边写盘。 ssid: 靶场 AP 的 SSID,作为变形基底 out_path: 输出文件路径,UTF-8 无 BOM、LF 行尾 """ seen = set() # 唯一的常驻内存项,用于去重 def emit(pwd: str, f): # 短于 8 位的先卡掉,测了也没有参考价值 if len(pwd) < 8 or pwd in seen: return seen.add(pwd) f.write(pwd + "\n") with open(out_path, "w", encoding="utf-8", newline="\n") as f: # 1) SSID 的各种变形组合 base = [ssid, ssid.lower(), ssid.upper(), ssid.capitalize()] suffixes = ["", "123", "1234", "12345", "2024", "2025", "!", "@123", "#2024"] for b in base: for s in suffixes: emit(b + s, f) # 2) 号段前缀 + 5 位尾号,只铺常见号段,别把全空间打开 for prefix in ("130", "131", "135", "136", "138", "139", "150", "158", "186", "199"): for tail in itertools.product("0123456789", repeat=5): emit(prefix + "".join(tail), f) # 3) 生日:年份 + 月日,只取几个常见日 for year in range(1970, 2026): for month in range(1, 13): for day in (1, 8, 18, 28): emit(f"{year}{month:02d}{day:02d}", f) if __name__ == "__main__": gen_candidates("LAB-SELFTEST", "dict.txt")

几个参数和写法上的判断:

  • encoding="utf-8"配newline="\n":不要省这两个参数。Windows 上默认会写成 CRLF,某些校验流程读到行尾带回车的口令,永远匹配不上,而且不报错,能让你怀疑人生。带 BOM 的文件同理;
  • len(pwd) < 8这一刀很关键。低于 8 位的口令在任何现代硬件面前都不构成障碍,测出来的结论没有信息量;
  • 第 2 段只铺 10 个常见号段,代价是 100 万条,覆盖了绝大多数以手机号起密码的情况。要把全号段铺开是另一个量级的事,自查阶段没必要;
  • 去重集合seen是唯一常驻内存的东西,跑百万级还行,上千万级就要考虑换成布隆过滤器或者干脆按段分文件。

4.3 把“能不能”换成“多久”:耗时账怎么算

校验速度和候选数量的乘积就是总耗时,公式很简单:

总耗时 ≈ 候选总条数 ÷ 每秒校验次数

每秒校验次数取决于硬件和派生迭代次数,同一台机器上基本是个常数。把这个常数代进去,几种口令形态的差距一目了然:

口令形态候选空间按每秒 20 万次估算
8 位纯数字10^8约 8 分钟
8 位小写字母26^8 ≈ 2.1×10^11约 12 天
10 位大小写 + 数字62^10 ≈ 8.4×10^17按万年计
12 位混合含符号约 5×10^23天文数字

这张表给出的结论比任何口头建议都硬:长度的收益是压倒性的,字符集是次要的。从 8 位纯数字到 8 位小写字母,多了不到二十倍的空间,耗时从分钟级跳到天级;而从 8 位加到 10 位混合,直接跳到万年。所以加固的顺序应该是先把长度拉起来,再考虑加符号。

反过来看,如果你的口令是“名字拼音 + 生日”,它的候选空间看着不小,但只要落进上面那张字典表的任何一行,实际耗时就是秒级。真正决定强度的不是字符集,而是它是否落在一个可以枚举的模式里。

5. 避坑与排查:六个把整晚时间烧掉的坑

下面六条都是我在模拟项目X上真实翻过的车,按“现象 → 原因 → 解决”写,遇到类似情况可以直接对号入座。

5.1 环境与采集环节的三次翻车

坑一:抓了一晚上,全是信标帧,一个协商帧都没有

现象:抓包文件几百兆,打开一看密密麻麻全是同一类帧,解析器输出空字典。

原因:监听接口没锁信道,或者锁的信道跟 AP 实际信道不一致。监听口默认会跳,看起来在收,其实大部分时间在别的信道上。

解决:iw dev wlan1 info复核信道,和 AP 管理后台里的信道设置逐个对齐。2.4G 只有 1、6、11 三个不重叠信道,别填 3 这种。

坑二:有协商帧,但校验始终不匹配

现象:解析出来的四条消息齐全,字典里明明有正确口令,跑完就是不出结果。

原因:SSID 对不上。中途改过 SSID、换过隐藏 SSID 设置,或者靶场里有两个同名但不同 SSID 的设备。SSID 是盐,差一个字符全套作废。

解决:从抓到的帧里直接读 SSID 字段,跟字典生成时传入的ssid参数逐字节比对,不要凭记忆填。

坑三:一触发重连,客户端就再也不回来了

现象:主动断开一次之后,客户端长时间不重连,甚至直接切到别的网络去了。

原因:客户端启用了更严格的保护机制,或者系统层面把这次断开判定为异常并拉黑了该网络。

解决:先用被动等待,让客户端保持待机再唤醒;实在不行就在客户端侧手动“忘记网络”后重连一次,这一次握手一定完整。别反复触发,触发次数越多,客户端越不愿意回来。

5.2 校验与结果解读环节的两次误判

坑四:字典里有,就是跑不出来

现象:手工确认字典文件里存在正确口令,校验流程跑完零命中。

原因:编码问题。文件带 BOM 或者行尾是 CRLF,读进来的口令末尾多了一个不可见字符,算出来的摘要自然对不上。

解决:file看一眼编码,xxd看头几个字节有没有 BOM,cat -A看行尾是不是^M$。生成时就固定用 UTF-8 无 BOM、LF 行尾,别等到出事再查。

坑五:跑出结果了,但那个口令根本不是真的

现象:校验报告命中,拿结果去连却连不上。

原因:比对逻辑写错了。常见的是 MIC 截断长度不一致,或者把组密钥消息当成成对密钥消息参与校验,导致误报。

解决:校验前用is_pairwise过滤掉组密钥消息,MIC 比对长度严格按协议规定的字节数来。命中之后必须做一次复验——用命中的口令重新算一遍完整链路,跟抓包结果逐字段对齐,两道都对上才算数。

5.3 收尾前必须确认的一件事

坑六:跑完不清理现场,第二天发现网络用不了

现象:测试结束之后,靶场 AP 连不上了,或者监听主机上不了网。

原因:监听接口没有切回托管模式,或者信道改完没恢复。

解决:收尾固定三步——ip link set wlan1 down、iw dev wlan1 set type managed、ip link set wlan1 up。把这三步写成一个脚本,跑完测试就执行,不要靠记性。

注意:上面六个坑里,前三个通不过就说明数据不可信,后三个通不过就说明结论不可信。两种情况都不要继续往下推。

6. 收口在加固:一张清单把口令这件事做对

跑完自查之后,最有价值的部分不是“我破了我的密码”,而是知道了哪一层的防护实际起了作用、哪一层是纸糊的。我的结论很明确:在这个场景里,长度是唯一划算的投入,其余都是次要项。

针对自己管的网络,我会按下面这张清单逐项过一遍:

检查项建议做法判断依据
加密套件WPA2-PSK(CCMP) 起步,设备支持就上 WPA3-SAESAE 握手不提供可离线校验的材料,从协议层堵死字典
口令长度不低于 12 位,优先拉长度而非堆符号8 位到 10 位的耗时跨度是分钟到万年
口令来源不用 SSID、门牌、电话、生日及其变形自查字典的第一批候选就是这些
WPS关闭PIN 是独立于握手的另一条路径
管理后台改默认口令、关闭远程管理握手这条路走不通时,人都会从这里进
访客网络单独 SSID,开启客户端隔离降低一台设备出问题后横向扩散的范围
固件跟随厂商更新老固件里的已知问题往往比口令弱得多

这张表里最容易被忽略的是最后两行。绝大多数真实发生的网络问题,入口根本不在口令强度上,而在管理后台的默认口令、以及一台被攻陷的设备能横向走到哪。把口令从 8 位拉到 12 位,收益是线性的;把访客网络和主网络隔开,收益是结构性的。

至于自查节奏,我现在的习惯是每个季度跑一次,流程固定成四步:拿一台备用路由搭靶场、用当期字典跑一遍、记录命中耗时、对照清单改配置。字典不用每次重造,但每半年要把新出现的常见模式补进去——起密码的习惯是会跟着热点变的,去年还管用的字典,今年可能就漏了。

回过头看,我最早做这件事的时候,把八成精力花在了“怎么抓到包”上,剩下两成花在“怎么跑得快”上,唯独没花时间想“抓到之后我要改什么”。结果第一次跑完,命中记录躺在文件夹里三个月没人看。从那以后我每次搭完靶场,第一件事是把加固清单打印出来贴在显示器边上,跑出结果当场对照着改,改完再拆环境。测试的价值不在结果本身,在你拿它换来了什么动作。

这套流程和那份清单我都整理好了,照着搭一遍,一个晚上能跑完;希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询