资讯动态

WiFi密码安全加固:WPA2四次握手、弱口令与路由防护

发布时间:2026/10/29 11:28:22 来源:尧图企业网站定制
简介无线网络安全的核心常被误解为加密算法强弱实际在 WPA2-PSK 体系里四次握手会产生可离线校验的 MIC口令熵因此成为主要防线。PBKDF2 迭代与抓包验证原理决定了弱口令在离线比对前几乎无效而长随机口令能把攻击成本推到不现实量级。理解这一机制有助于把家庭路由器加固落到后台口令、WPS/UPnP 关闭、访客隔离和固件更新并用 ARP 表与 DHCP 租约做定期对账及时发现异常接入。1. 搜破解 WiFi 密码的人八成该做的是自家网络体检后台检索词里破解 WiFi 密码这条流量一直不小但真摸过来的多数不是要攻破谁家网络而是三种人忘了自家路由器后台口令的、怀疑被人蹭网想确认的、以及被房东塞了一条不知道密码的宽带的。这三种诉求的落点都不是攻而是查和防。这篇笔记走防御侧从一个完整握手里能推出什么、推不出什么讲到家用路由器从后台入口到固件版本的加固清单再给一套每月跑一次的接入设备对账脚本。适合家里挂着一堆智能设备、手上管着三五台路由、又不想在这件事上翻车的人。任何针对他人网络的操作都不在讨论范围。2. 四次握手拆开看WPA2-PSK 究竟把什么交给了运气无线安全这块最常见的误解是以为加密强度决定一切。实际在 WPA2-PSK 这套体系里算法本身到今天仍然站得住真正被反复击穿的是口令。要理解这一点得把接入过程拆到帧级别看看清楚哪一步是可离线验证的、哪一步必须在线交互。这个差别直接决定了一件事为什么强口令能把攻击成本推到不现实的量级而弱口令等于没设。2.1 从 WEP 到 WPA3三代方案各自栽在哪WEP 的问题在 IV 复用和 CRC32 校验。24 位初始向量在高流量下必然碰撞而 CRC32 是线性的异或运算下能推出密钥流于是收集足够多的包就能反推。这一代方案的失败是设计层面的跟口令长度无关改口令救不回来。WPA 作为过渡方案保留了 TKIP仍然基于 RC4只是加了每包密钥混合和 MIC 完整性校验缓解了但没根治。真正的分水岭是 WPA2 强制启用 CCMPAES-128 计数器模式。AES 本身没有已知的实用攻击路径所以从 WPA2 开始攻击面就从破解加密整体转移到了猜口令。WPA3 改的是握手环节。它用 SAE对等实体同时认证替换了 PSK 的四次握手基于 Dragonfly 交换每次口令猜测都必须和 AP 实时交互一次离线批量比对这条路被堵死。同时 SAE 有抗降级设计防止有人诱导客户端退回 WPA2。代价是老设备兼容性和部分实现早期的侧信道问题家用场景下要不要开得看终端清单。家用路由的现状是三代并存2.4G 频段为了照顾老设备常留 WPA2 混合模式5G 频段可以单独开 WPA3。常见做法是 5G 走 WPA3、2.4G 留 WPA2/WPA3 混合先跑一周看有没有设备掉线再决定是否全量切换。2.2 抓一个完整握手里面到底有什么802.11 的接入分两段先是链路层的开放认证和关联这一段不涉及任何密钥谁都能完成之后才是安全层的四次握手EAPOL 帧。四次握手的报文序列是固定的四步第一步 AP 发给客户端一个 ANonce这是个一次性随机数。第二步客户端生成自己的 SNonce连同自己的 MIC 一起回给 AP。第三步 AP 下发组播密钥 GTK 并附带 MIC。第四步客户端回一个 ACK 确认。关键在于 PTK 的推导PMK PBKDF2-HMAC-SHA1(passphrase, SSID, 4096, 256) PTK PRF-512(PMK, Pairwise key expansion, min(AP_MAC,STA_MAC) || max(AP_MAC,STA_MAC) || min(ANonce,SNonce) || max(ANonce,SNonce))PTK 再切分成 KCK、KEK、TK 三部分其中 KCK 用来算 EAPOL 帧的 MIC。而 MIC 是明文传输的。这就形成了一个可离线验证的闭环已知 SSID、已知两个 MAC、已知两个 Nonce、已知一段明文 EAPOL 帧和它的 MIC就可以对任意候选口令算出 PMK→PTK→MIC比对一次即可。整个过程不需要再碰 AP 一下。我在自家设备上做过一次验证用一台闲置路由开一个测试 SSID客户端连上去在监听模式下抓到包含完整四帧的握手。整个过程里 AP 毫不知情抓包侧也没有任何异常。这就是黑匣子式的隐患——握手报文是设计上就要在空中广播的防不住被动接收。反过来说抓不全四次握手就没法验证。缺了第一帧拿不到 ANonce缺了第二帧拿不到 SNonce 和 MIC两者缺一不可。这也是为什么实践中要反复踢客户端重连来凑齐握手属于典型的看运气环节。而 WPA3 的 SAE 交换里根本不存在这样一个可离线比对的 MIC所以这条路走不通。2.3 为什么弱口令在离线比对面前等于没有把上面那条链路反过来看防御逻辑就清楚了PTK 推导里的所有输入除了 passphrase其余全是公开量。也就是说口令是唯一的信息熵来源。攻击方拿到一个握手之后可以离线、并行、无限次地试不受 AP 速率限制也不会触发任何告警。这一点和在线撞库完全不同。在线验证受限于 AP 的响应速度和失败锁定策略每秒几次就是上限离线比对可以堆显卡每秒几十万次起步。量级差了三到四个数量级这就是为什么防爆破的思路在无线场景里必须转成把口令做长。所以那些改成 8 位字母加生日的加固建议基本没有意义。8 位纯小写是 26 的 8 次方约 2×10^11同样长度换成大小写加数字是 62 的 8 次方约 2×10^14看着涨了三个数量级但在离线比对的算力面前仍然只是一个时间问题。真正起作用的是长度和随机性叠加——12 位以上的随机串才把空间推到需要以年为单位衡量的区间。3. 口令强度的算力账12 位随机串为什么基本劝退上一章把问题收敛到了口令熵这一个变量上。这一章把它量化一次 PBKDF2 到底多贵不同字符集和长度对应的搜索空间有多大以及常见的弱口令长什么样子。算清楚这笔账后面配口令就不用凭感觉了。3.1 一次 PBKDF2 迭代值多少钱WPA2-PSK 的口令派生用的是 PBKDF2-HMAC-SHA1迭代 4096 次输出 256 位。这个迭代次数是 2004 年定的当时的意图就是拖慢暴力枚举。它确实起作用但作用有限现代显卡跑 SHA1 是每秒几十亿次哈希的量级除以 4096 之后单个 GPU 每秒能试的候选口令仍在几十万到上百万之间。下面这段脚本用来估算搜索空间和粗略的穷举耗时参数都摆在明面上改数字就能算自己的场景import math # PBKDF2-HMAC-SHA1 迭代次数WPA2-PSK 规范固定值 ITER 4096 # 单个 GPU 每秒能完成的 SHA1 计算次数数量级参考值按中端卡估 SHA1_PER_SEC 3.0e9 # 折算成每秒可验证的候选口令数 GUESS_PER_SEC SHA1_PER_SEC / ITER CHARSETS { 纯小写: 26, 小写数字: 36, 大小写数字: 62, 大小写数字符号: 94, } def human(seconds: float) - str: 把秒数转成人能读的单位 units [(秒, 1), (分钟, 60), (小时, 3600), (天, 86400), (年, 86400 * 365)] for name, scale in reversed(units): if seconds scale: return f{seconds / scale:.2e} {name} return f{seconds:.2e} 秒 for name, size in CHARSETS.items(): for length in (8, 10, 12, 16): space size ** length # 候选口令总数 secs space / GUESS_PER_SEC # 全空间穷举耗时 print(f{name:12} 长度{length:2}: 空间 {space:.3e} 穷举约 {human(secs)})跑出来会看到几条分界线8 位纯小写在几分钟到几小时之间8 位大小写加数字到了以天计12 位大小写加数字跳到以百万年计。这里的GUESS_PER_SEC是数量级参考实际值取决于显卡型号和优化程度可能差一到两个数量级但不影响结论的方向——长度收益是指数级的字符集收益是底数级的。顺带说一句别被平均值骗了。字典攻击不是均匀遍历全空间它按常见口令的分布排序前一万个候选就能覆盖相当比例的真实口令。所以上面这张表只对真随机的口令有效对Abc123456这种无效。3.2 弱口令的五种典型长相整理过一批公开泄露口令样本之后家用 WiFi 口令的高频模式基本就五类第一类是手机号、门牌号、生日这类数字串11 位看着长实际搜索空间只有 10 的 11 次方而且候选高度集中在几个号段实际熵远低于理论值。第二类是路由器出厂默认比如厂商名加几位数字的组合。这类口令能在公开的默认口令表里直接查到属于零成本。第三类是键盘走位qwerty、1qaz2wsx、asdfgh。所有像样的字典都会优先收录。第四类是拼音加数字比如名字全拼加生日。这类在中文场景下命中率极高因为字典本身就是按这个思路构造的。第五类是看起来复杂其实规律的大小写加符号但用的是Pssw0rd这种经典替换。替换规则是有限的字典生成器会穷举常见替换组合。血泪经验是只要口令能被人一眼记住并且说出构成逻辑它就在上面五类里。真正安全的随机串是不该被记住的——这也是为什么下面要讲保管方式而不是继续念要设复杂密码。3.3 生成与保管一条能落地的规矩我的做法是把记住和使用拆开。WiFi 口令本身用真随机生成20 位大小写数字符号混排自己也不记唯一需要记的是一个主口令用来解锁密码管理器。生成这一步不需要联网本地跑就行import secrets import string # 去掉了容易混淆的 0/O、1/l/I方便手工输入到不支持扫码的设备 ALPHABET .join(c for c in (string.ascii_letters string.digits !#$%^*-_) if c not in 0O1lI) def gen(n: int 20) - str: # secrets 走的是操作系统 CSPRNG不要用 random return .join(secrets.choice(ALPHABET) for _ in range(n)) if __name__ __main__: print(gen())几个参数值得说明。ALPHABET剔除了六个易混字符实际字符集约 70 个20 位的空间约 70^20 ≈ 8×10^36比表里 94 字符集 16 位还高一截。用secrets而不是random是关键后者是可预测的梅森旋转做密钥材料不合格。落地时有几件事要一起做。SSID 别用门牌号或姓名它和口令一起进 PBKDF2 的 salt 位置泄露 SSID 等于白送一半输入改成中性名字。生成的口令立刻写进密码管理器同时在路由器后台贴上二维码访客来扫一次就行。别用 WPS 的 PIN 配网来图省事那是另一个话题下一章讲。注意改完 WiFi 口令之后所有 IoT 设备都要重新配网。建议先改 5G 频段观察一天再改 2.4G避免一次性全掉线找不到是哪台设备的问题。4. 家用路由器加固清单从后台入口到固件版本口令做厚只解决了接入认证这一段。整台路由器的攻击面远不止这里——管理后台、WPS、UPnP、远程管理、固件版本每一项都是独立入口。我见过口令设了 24 位随机串结果后台还是出厂默认 admin/admin 的情况前面那些功夫等于白做。4.1 管理后台的三道门第一道是后台登录口令。这一条和 WiFi 口令必须不同很多人图省事设成一样一旦 WiFi 口令因为共享给访客而泄露后台跟着失守。后台口令不需要能背写进密码管理器即可。第二道是后台的访问范围。绝大多数家用路由的管理页面默认对整个 LAN 开放也就是任何一个连上来的设备都能访问。能限制来源 IP 的型号就限制到自己常用的那几台不能限制的至少确认 WAN 侧管理端口是关闭的。第三道是会话与认证方式。优先选支持 HTTPS 的后台别用 HTTP 明文登录——同网段抓个包就能拿到口令。部分型号支持登录失败锁定有就开虽然对局域网内的攻击者作用有限但能挡住自动化脚本。4.2 WPS、UPnP、远程管理能关就关WPS 的 PIN 码是 8 位数字其中最后一位是前七位的校验位实际只有 10^7 的空间。而且协议设计上允许分段验证前四位和后四位分开试实际尝试次数降到万级。这个设计缺陷是结构性的不是实现问题所以改个 PIN没有意义唯一正确的操作是关掉 WPS。UPnP 的风险在于它允许内网设备自主在路由器上开端口映射不需要任何认证。一个被植入的 IoT 设备可以通过 UPnP 把自己暴露到公网。家用场景下除非确实需要 P2P 下载或游戏联机否则建议关闭需要时按需临时打开。远程管理WAN 侧 Web 访问、Telnet、SSH在同一台设备上同时开着公网入口和弱口令是最典型的组合风险。家用宽带绝大多数没有固定公网 IP这个功能基本用不上直接关闭。项目建议值理由WPS / QSS关闭PIN 分段验证空间仅万级UPnP关闭按需临时开无认证开端口IoT 被控后可自曝WAN 侧管理关闭公网入口叠加弱口令风险最高Telnet关闭明文传输无必要HTTP 后台改 HTTPS防同网段抓包访客网络开启并隔离降权接入阻断横向访问固件自动更新开启补丁是最低成本的加固4.3 访客网络与 IoT 隔离这一条被低估得最厉害。家里所有设备塞进同一个网段意味着任何一台被控的设备都能直接访问内网其他主机包括 NAS、摄像头和后台管理页。合理的三段划分是主网络放手机和电脑访客网络放来客设备IoT 网络放摄像头、扫地机、智能音箱这类长期不更新的设备。三段之间做客户端隔离只允许 IoT 段访问公网、不允许访问主网段。多数中高端家用路由支持访客网络和 AP 隔离但访客网络能否访问内网这个开关的默认值各家不同配置完一定要实测连上访客网络试着 ping 主网段的一台设备通就说明隔离没生效。摄像头这类设备尤其要注意。它们通常需要外网访问才能远程查看如果和主网段同域一旦固件有漏洞攻击者就能横向摸到你的电脑。放在隔离段里最坏情况也只丢摄像头本身。4.4 固件与配置备份固件更新是最容易被忽略的一项。家用路由的漏洞公告不少厂商发了补丁但用户不更新等于没修。建议开自动更新或者至少每季度手动查一次。不放心自动更新的可以手动流程先在后台导出当前配置备份再升级固件升级完确认配置还在最后把备份文件存到本地。注意配置备份文件里包含 WiFi 口令和后台口令的通常是加密或哈希后的副本别随手丢在共享盘里。还有一条容易被忘换路由器的时候旧设备恢复出厂设置再处理掉。后台配置里存着 PPPoE 账号、WiFi 口令、端口映射这些都是明文或弱加密的。5. 排查避坑六类翻车现场与对账思路加固做完了不等于就安全了。实际运维里翻车的往往不是配置本身而是以为配好了。这一章列几条我踩过或者见别人踩过的按现象、原因、解决来写。5.1 现象改了 WiFi 口令网速反而变慢原因通常不是口令本身而是改完之后设备重新协商一部分老设备掉回了 2.4G 频段并启用了低效的兼容模式也可能是改口令时顺手改了加密方式从 WPA2 混合切成了纯 WPA3老设备连不上就在那反复重连把空口占满了。解决先看路由器的连接列表确认在线设备数和预期一致再把加密方式退回 WPA2/WPA3 混合观察 24 小时。如果确实需要纯 WPA3把不支持的设备单独挪到一个 2.4G 的 WPA2 专属 SSID 上。5.2 现象后台登录不上去了最常见的原因是改了后台口令但没记进密码管理器或者改了后台访问限制把自己的设备 IP 排除了。还有一种情况是浏览器缓存了旧会话看着像登录失败其实是跳转循环。解决先换无痕窗口排除缓存不行就用网线直连路由 LAN 口把本机设成同网段的静态 IP 再试还不行就按复位键恢复出厂重新配一遍。这也是为什么每次改后台配置前导出备份是值得的。5.3 现象访客网络设了隔离还是能访问 NAS原因是很多路由的访客网络隔离只管无线侧客户端之间的互访不管访客段到主网段的转发这两个是独立开关界面上的措辞也经常混用。解决配完必须实测。连上访客网络用ping打主网段一台已知在线的设备再用浏览器访问那台设备的 Web 端口。全不通才算隔离生效。另外确认 NAS 本身没有开 UPnP 自动映射。5.4 现象设备列表里有一台不认识的设备先别急着判断是被蹭网。常见的情况是智能插座、电视盒子这类设备用了随机化 MAC每次重连都换一个地址或者是 Mesh 子节点被识别成了独立设备也有可能是邻居家的设备在信号边缘反复尝试关联但没成功出现在扫描列表里却没真正接入。解决看 DHCP 租约而不是只看在线列表租约里有分配时间和主机名能区分扫到和接入。再把已知设备的 MAC 手动绑定成静态租约之后就只需要关注租约表里新增的条目。5.5 现象改完配置过几天又变回去了一部分家用路由在固件升级或者断电重启后会回滚部分配置尤其是通过非官方途径刷过固件的设备。另一种可能是同网段有人能访问后台把配置改回去了。解决改完配置立刻导出备份重启一次再核对关键项WPS 状态、远程管理、访客隔离。同时确认后台口令已经改掉并且没有多个管理员账号。5.6 现象抓包看不到想要的报文如果是为了自查而抓包常见失败原因是网卡不支持监听模式或者只抓到了管理帧没抓到数据帧再有就是客户端在抓包期间没有重新握手——不重连就不会产生新的四次握手。解决确认网卡和驱动支持监听模式抓包时让目标客户端断开重连一次抓完先看有没有成对的 EAPOL 帧没有就重来。6. 每月一次的对账用 ARP 表和 DHCP 租约把异常设备揪出来加固和排查都做完最后落在一个习惯上定期对账。设备是不是多了、租约是不是异常这些事靠感觉判断不了得让数据说话。最轻量的做法是拉 ARP 表和 DHCP 租约做交叉比对。ARP 表反映当前这一刻的邻接关系租约反映曾经分配过的记录两者对不上就值得看一眼。下面这段脚本做的是采集和初步比对逻辑很简单胜在能定时跑import re import subprocess import sys def arp_neighbors() - dict: 读取本机 ARP 邻居表返回 {ip: mac} if sys.platform.startswith(win): # Windows: arp -a 输出里 MAC 用 - 分隔 out subprocess.run([arp, -a], capture_outputTrue, textTrue, errorsignore).stdout pat re.compile(r(\d\.\d\.\d\.\d)\s([0-9a-fA-F-]{17})) else: # Linux: ip neighMAC 用 : 分隔 out subprocess.run([ip, neigh], capture_outputTrue, textTrue).stdout pat re.compile(r(\d\.\d\.\d\.\d)\s.*?lladdr\s([0-9a-fA-F:]{17})) table {} for ip, mac in pat.findall(out): # 统一成小写冒号格式方便和租约表比对 table[ip] mac.lower().replace(-, :) return table if __name__ __main__: neighbors arp_neighbors() for ip, mac in sorted(neighbors.items(), keylambda x: tuple(map(int, x[0].split(.)))): # 第一个字节的第二位为 1 表示本地管理地址常见于随机化 MAC randomized bool(int(mac.split(:)[0], 16) 0x02) flag 随机化 MAC if randomized else print(f{ip:16} {mac}{flag}) print(f\n共 {len(neighbors)} 台在线邻居)逻辑上有两点要说清楚。一是arp -a和ip neigh都只反映本机近期通信过的邻居没通过信的设备不会出现所以它是个采样而非全量。要全量就得登路由器后台拉 DHCP 客户端列表或者用 ICMP 扫一遍网段把 ARP 缓存填满——前者更准后者更快。二是那个随机化 MAC 的判断。MAC 首字节的第二个比特是本地管理位置 1 就说明这个地址不是厂商烧录的而是软件生成的。手机和部分 IoT 设备的隐私 MAC 会置这一位。它本身不是威胁信号但如果你看到一台标着随机化 MAC 的设备主机名又是陌生的那就值得点进去看看。对账的正确姿势是拿三次结果比这个月的在线列表、上个月的在线列表、路由器的 DHCP 租约全表。只出现在租约里从不在线的可能是历史记录或者边缘信号设备只在线不在租约里的可能是静态 IP 设备两边都没有但 MAC 陌生的才是真正要看一眼的。我把这套东西固化成了一个每月 1 号早上跑的定时任务输出一份 diff 发到自己邮箱。第一次跑的时候确实抓到过一台不知道哪来的设备查了半天发现是电视盒子在待机状态下用了另一个 MAC 重连——虚惊一场但那次之后我才意识到光看路由器后台那个在线设备列表根本不够它只显示当前活跃的待机设备一会儿在线一会儿离线人工看是看不全的。从那以后我每次动路由器配置都会先导一份配置备份、跑一次对账留个基线改完再跑一次对比差异。这个习惯帮我省过至少两次重配。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑