资讯动态

WPS PIN码为何几小时被攻破:拆半验证与默认PIN派生

发布时间:2026/10/25 1:07:28 来源:尧图企业网站定制
简介这份DOCX文档围绕无线路由器PIN码算法的破译与防护展开面向网络安全初学者、无线网络运维人员及希望了解WPS风险的读者帮助其在授权环境中理解PIN码推算思路与无线加密防护要点。压缩包仅含1个DOCX文件大小约191KB内容以图文讲解方式组织便于直接阅读和检索关键概念。资源已有1185人学习下载说明该主题在无线安全入门学习中具有一定关注度。文中结合扫描附近无线信号、获取MAC地址与SSID等信息、十六进制转十进制推算PIN码等案例并讨论关闭WPS功能、启用WEP/WAP协议等防护措施读者可从中获得PIN码算法原理、WPS后门风险认识以及基础无线网络安全加固思路适合作为概念梳理与风险自查的参考材料。1. 八位数字的错觉无线路由器 PIN 码算法被攻破的从来不是加密很多人第一次听到无线路由器 PIN 码算法被攻破第一反应是 WPA2 不行了。事实恰好相反这类事件里加密算法毫发无损被撬开的是设备主动敞开的一条配置通道——WPS。更反直觉的是PIN 只有八位十进制数按一亿种组合硬猜要按月计可实际在线交互次数被压到一万一千次上下一台设备几个小时就能出结果。整个过程中没有一处依赖算力全是协议在每一步把信息一点点漏给了对面。搞懂这条链路比记住“关掉 WPS”这句结论有用得多因为默认凭据、派生凭据、错误反馈这三样东西今天仍然大量出现在各类设备的配网流程里。2. WPS 协议栈一个“让配置变简单”的设计如何造出可探测的身份通道2.1 注册器与入网者WPS 到底替谁做了决定WPS 是 Wi-Fi 联盟在 2006 年前后推出来的东西动机非常朴素那个年代家用路由刚普及让普通用户进后台选加密方式、敲一串十六进制 PSK成功率极低。WPS 提供了两条路一条是按键PBC按一下路由器上的按钮两分钟内新设备自动入网一条是 PIN输入设备背面贴纸上的八位数字。按键模式解决“没有键盘的设备”PIN 模式解决“没有按钮的设备”两条路一起覆盖了当年的消费级场景。协议里有两个角色。Registrar 是“发放配置的一方”负责把 SSID、加密方式、网络密钥打包下发给对方Enrollee 是“申请入网的一方”拿着自己的 Device Password 证明身份。关键点在于出厂贴纸上的那八位 PIN就是这台设备作为 Enrollee 时的 Device Password。它不是为了给用户登录后台用的而是为了让一台外部 Registrar 能把配置推给它——设计初衷是“你买了新路由用手机 App 扫一下贴纸 PIN手机当 Registrar 把家里网络配好”。这个角色设计埋下了第一个隐患PIN 是一份长期有效的静态凭据贴在设备外壳上几年都不会变。它不随 Wi-Fi 密码修改而失效也不随固件升级而轮换。用安全工程的视角看这相当于在 WPA2 那把锁旁边永久性地留了一把挂锁钥匙还印在门牌上。第二个隐患是发现机制。为了让人知道“我这台设备支持 WPS”AP 会在 Beacon 帧和 Probe Response 帧里挂一个厂商自定义信息元素Element ID 0xDDOUI 00:50:F2Type 0x04里面带着 WPS 版本属性 0x104A、设备名0x1011、配置方法0x1008、以及 Device Password ID0x1012。Device Password ID 取 0x0000 表示“默认 PIN 模式可用”取 0x0004 表示“按键模式”。也就是说一台开启了 PIN 模式的路由器会在空气里持续广播“我这里可以用贴纸 PIN 配网”。这是黑匣子被打开的第一道缝——不需要认证不需要关联扫一圈就全知道了。提示这些属性在 WPS 规范里属于“设备信息”本意是方便用户识别该连哪台设备、该用哪种方式配网不是机密字段。设计上它被当作公开信息处理问题出在它与后面的静态凭据绑在了一起。2.2 EAP-WSC 的八条消息M1 到 M8 里泄露了什么WPS 的配网会话跑在 EAP 之上具体叫 EAP-WSC封装在 EAPOL 帧里EtherType 0x888E。整个握手是八条消息M1 到 M8双方用 Diffie-Hellman 交换出一个共享密钥再用 PIN 派生的密钥去保护两个随机数 R-S1 和 R-S2。流程大致是这样M1Enrollee → Registrar携带 Enrollee Nonce、可选的 DH 公钥、厂商信息M2Registrar → Enrollee回 Registrar Nonce 和 DH 公钥M3 确认双方公钥共享密钥成型M4Registrar → Enrollee发送 R-S1用 PIN 派生的密钥加密M5Enrollee → Registrar回 E-S1同样用 PIN 派生的密钥加密M6Registrar → Enrollee发送 R-S2M7Enrollee → Registrar回 E-S2M8Registrar → Enrollee收尾下发配置。真正的要害在密钥派生的粒度上。规范没有用完整的八位 PIN 去派生一把密钥而是把它切成两段PIN 的前四位参与派生保护 M4/M5 的密钥后四位参与派生保护 M6/M7 的密钥。这种切分是有实现层面的考虑的——它允许 Registrar 先验证前四位、再验证后四位输入错了只需要重输一段也让一些没有完整键盘的设备可以分两次录入。用可用性换复杂度看起来划算。代价是验证被拆成了两次独立的判定而每次判定都会产生一个明确的结果信号。这个信号就是 EAP-NACKWSC 里叫 WSC_NACK。当 Enrollee 解不开 M4 里的 R-S1 时它会在 M5 的位置回一个 NACK解开了但 M6 里的 R-S2 对不上就在 M7 的位置回一个 NACK。对端收到 NACK立刻知道“这一段错了”。到这里问题就从“猜一个八位数”变成了“猜一个四位数再猜一个四位数”。而且这两段是被分开反馈的可以独立穷举。协议没有做任何节流设计的补偿规范里有一个 AP Setup Locked 属性0x1057本意是“配置流程进行中其他设备不要来抢”很多实现把它做成了软状态超时或重启就清空起不到限速作用。3. 校验位与拆半验证一亿种组合是怎么塌缩到一万一千次的3.1 最后一位不是密钥是校验和八位 PIN 里第八位不携带任何熵。它是前七位的校验和作用类似身份证号最后一位纯粹为了在手输的时候挡住“按错一个键”。算法在多个开源实现里都能看到思路是从最低位往上按 3、1 交替加权求和再对 10 取补。def wps_checksum(pin7: int) - int: WPS PIN 第 8 位前 7 位的校验和。 从最低有效位开始权重按 3、1 交替最后对 10 取补。 accum 0 n pin7 while n: accum 3 * (n % 10) # 当前最低位权重 3 n // 10 accum n % 10 # 次低位权重 1 n // 10 return (10 - accum % 10) % 10 # 取补后仍需再模 10处理余数为 0 的情况 # 校验7 位候选 5995737加权和 101余 1补 9 print(wps_checksum(5995737)) # 输出 9 print(f{5995737}{wps_checksum(5995737)}) # 完整 PIN59957379这段代码里两个参数值得说明。pin7是去掉校验位后的七位整数允许前导零丢失所以实际使用时通常用字符串补齐到七位再转整数。accum的加权方向是从个位开始这一点容易写反——如果从最高位开始加权算出来的校验位会对不上表现出来的现象是“算出来的 PIN 永远是错的”排查时优先怀疑这里。校验位带来的安全后果是有效搜索空间从 10^8 降到 10^7。这本身不算致命一千万次在线交互还是不可行。真正致命的是下一节。3.2 EAP-NACK 把“错在哪一半”告诉了对方把 3.1 的结论和 2.2 的拆半验证合起来看前四位独立验证后四位独立验证而最后一位由前七位决定、不需要猜。于是穷举前四位的代价是 10^4 次穷举后四位三位有效数字加一位算出来的校验位的代价是 10^3 次。def search_space(): 拆半验证下的实际尝试次数 first 10 ** 4 # PIN 前 4 位0000 - 9999 second 10 ** 3 # 后 4 位中只有 3 位可猜第 8 位由校验位定死 worst first second # 最坏情况 11000 次 avg first // 2 second // 2 # 平均情况 5500 次 return worst, avg worst, avg search_space() print(worst, avg) # 11000 5500参数含义很直白first是前四位全空间second是后四位去掉校验位后的空间。最坏一万一千次平均五千五百次。若一次 EAP-WSC 会话从发起到收到 NACK 平均耗时 0.5 到 2 秒取决于 AP 的状态机实现、信号质量和重传策略把这个区间代进去总耗时落在 45 分钟到 6 小时之间。原始事件里说的“两小时”正好在这个区间的中段属于合理估算而不是夸张。值得注意的是协议本身并没有“故意”泄露位置信息。EAP-NACK 是 EAP 框架的标准语义它要告诉对端“这次协商失败请重来”而重来的粒度就是当前这段密钥。设计者把 PIN 切成两段是为了让验证可以分段进行分段验证必然产生分段反馈分段反馈必然把搜索空间从乘法变成加法。这是一条很典型的因果链每一个单独看都合理的决定串起来就成了漏洞。注意很多人把这类攻击理解成“算力破解”于是下意识觉得换更强的加密、加更长的密码就能挡住。实际上被攻击的是配网阶段的身份验证通道跟空口加密强度没有关系。理解这一点才不会在错误的方向上加固。4. 从 MAC 到 PIN产线便利性如何变成一把批量钥匙4.1 默认 PIN 的推导链条取模、截断、补校验位如果说拆半验证把成本从“月”降到“小时”那么默认 PIN 派生把成本从“小时”降到“一次”。事情的起因在生产环节每台设备烧一个真随机 PIN意味着要在产线上生成随机数、写进固件、再同步到外壳贴纸的打印系统三处必须严格对齐任何一处错位都会导致用户拿到一台“贴纸 PIN 与固件不符”的机器。这在售后是灾难。于是有一部分批次的固件选择了另一条路——用 MAC 地址派生 PIN让贴纸打印机和固件用同一套规则各自算一遍永远不会对不上。推导形态大致如下def pin_from_mac(mac: str) - str: 默认 PIN 派生的一种历史形态 取 MAC 尾部 6 个十六进制字符 - 转十进制 - 截断到 7 位 - 补校验位 tail mac.replace(:, ).replace(-, ).upper()[-6:] n int(tail, 16) # 十六进制转十进制 cand n % 10_000_000 # 截断到 7 位不同固件取模位数不一样 cand_str str(cand).zfill(7) # 前导零补齐否则校验位会算错 return cand_str str(wps_checksum(int(cand_str))) demo 02:1F:3A:5B:7C:D9 # 虚构地址尾部 5B7CD9 5995737 print(int(5B7CD9, 16)) # 5995737 print(pin_from_mac(demo)) # 59957379两个参数要盯住。[-6:]取的是 MAC 尾部六个十六进制字符二十四位地址去掉 OUI 前缀后的设备部分正好六个字符这是最常见的取法。% 10_000_000是截断方式不同批次固件有的取模十的七次方有的直接取十进制字符串的低七位还有的只取六位。原始事件里那台设备算出来的350936只有六位数字这就是取六位变体的证据——它只给了 PIN 的前六位剩下一位加校验位靠猜所以原文才说“最后一位数字只要猜十次”。这个细节说明默认 PIN 派生没有统一标准它是一堆厂商各自实现的集合形态随批次漂移。安全后果非常直接MAC 地址是公开的。它在 Beacon 帧的地址字段里在每一次 Probe Request 里在 ARP 表里在任何一台能收到信号的设备上都能读出来。把一个公开值经过固定算法变换一次得到的仍然是公开信息。PIN 的保密性在这里被完全消解攻击者不需要在线交互扫到 MAC 就能离线算出 PIN然后一次性走完 WPS 绑定流程。原文说“涉及的 MAC 地址段不多”指的就是只有特定 OUI 前缀的批次用了这套派生其余设备仍然要靠拆半穷举。4.2 弱随机数另一条把在线交互压成离线的路径默认 PIN 派生依赖“厂商用了确定性算法”这属于实现缺陷覆盖面有限。后续公开研究里还出现过另一类问题根子在随机数生成器上覆盖面更广。回顾一下 M4 到 M7 的结构R-S1 和 E-S1 是双方各自生成的随机 secret它们被 PIN 派生的密钥包起来传输。如果 Enrollee 生成 E-S1、E-S2 时用的是低熵随机源——比如以开机时长、系统时钟的低位做种子或者直接用了一个被固定种子的伪随机函数——那么这两个 secret 的取值空间会小到可以枚举。攻击者只要抓到 M1/M3 里的 Nonce 和 M5/M7 里的密文就可以离线把种子空间跑一遍对每个候选种子重算 secret、重算密钥、尝试解密能解开的那个种子就锁定了 PIN。攻击路径依赖条件交互次数耗时量级拆半在线穷举仅需 PIN 模式开启约 11000 次小时级默认 PIN 派生特定批次固件1 次秒级弱随机数离线枚举随机源熵不足1 次捕获分钟到小时级这张表想说明的是同一个结构性事实WPS 的安全性完全建立在“PIN 是秘密”这个假设上。一旦 PIN 可以从 MAC 推出来或者保护 PIN 的随机数可以被枚举整个机制的信任根基就没了。协议层再加固也没用因为泄露发生在协议之下的实现层。5. 排查与避坑为什么“已经关了 WPS”设备仍在应答5.1 五个被反复误读的现象现象一后台里把 WPS 关掉了扫描工具还是能看到这台设备带 WPS 信息。原因多半是界面上的开关只关掉了按键模式PIN 模式仍在 WSC 状态机里注册着。这两条路在实现里经常是两个独立配置项UI 只暴露了其中一个。解决办法是回到 Beacon 帧里看 Device Password ID 字段如果它仍然是 0x0000说明默认 PIN 模式还活着界面上那个开关没有真的生效。现象二隐藏 SSID、开 MAC 白名单就觉得安全了。隐藏 SSID 只是不广播 SSID 字段Probe Response 里该带的 WSC 信息元素一个不少设备名、型号、配置方法全都还在。MAC 白名单的作用点在关联阶段而 WPS 的信息暴露发生在关联之前。这两项措施对配网通道的暴露面没有任何收缩作用属于典型的“加固了错误的那一层”。现象三“我 WPA2 密码设了二十多位怎么还被破了”。因为对方根本没有碰四次握手。WPA2 的强度保护的是数据面WPS 保护的是配置面两者是并列的两扇门。配置面被打开之后网络密钥是被“下发”出来的不是被“算”出来的密码再长也不参与这个过程。这个误解在实际排查里出现频率最高也最容易让人得出错误结论。现象四PIN 试错几次之后设备好像锁了等一会儿又活了。这类锁定通常是软件层的计数器存在内存里超时清零或者重启清零。考虑到拆半验证只需要在后半段成功一次就能收敛这种量级的节流对整体耗时的影响很有限。把限速当成主要防线是血泪经验里最常见的一条弯路。现象五双频路由器只关了一个频段的 WPS。2.4G 和 5G 在部分固件里是两个独立的无线实例各自跑一套 WSC 状态机配置项也是分开的。关掉 2.4G 那个5G 那个照样在 Beacon 里挂着 WPS 信息元素。验证时要把两个频段分别扫一遍别只看一个就下结论。5.2 验证动作从 Beacon 里的 WSC IE 开始判断一台设备是否真的关干净了最可靠的办法不是看后台界面而是看空口上还在广播什么。思路是抓一小段 Beacon 和 Probe Response解析里面的厂商自定义信息元素确认三件事WSC IE 是否还存在、Device Password ID 的取值是什么、AP Setup Locked 是否被置位。# 伪代码从 Beacon 帧的 information elements 里筛出 WSC IE def find_wsc_ie(ies: bytes): i 0 while i 2 len(ies): eid, elen ies[i], ies[i 1] body ies[i 2: i 2 elen] # Element ID 0xDD 是厂商自定义OUI 00:50:F2 Type 0x04 才是 WSC if eid 0xDD and body[:4] b\x00\x50\xf2\x04: return body[4:] i 2 elen return None # 返回非 None 就说明这台设备仍在广播 WPS 能力这段代码只做一件事在信息元素列表里按(Element ID, Length, Body)三元组顺序遍历命中 OUI 为00:50:F2、类型为0x04的那一条就返回。参数上要注意长度字段是单字节最大 255遍历时的步进必须是2 elen少加这个 2 就会在第二个元素处错位读出来的全是垃圾数据——这是自己写解析器时最容易翻车的地方。拿到 WSC IE 之后再往里找属性 0x1012。取值为 0x0000 表示默认 PIN 可用这时候真正有效的动作只有两个在固件里彻底关掉 PIN 模式不是关按钮或者换一台允许你关干净的设备。如果固件压根没提供这个选项那这台设备在网络边界上就应该被当成一台“配置面不可信”的设备来处理比如只让它做纯 AP、把管理面隔离出去、或者干脆降级成访客网络用。6. 设计取舍把可用性放进安全通道要付多少利息6.1 默认值与派生凭据的原罪回头看这条链路真正值得记住的不是某个算法而是三个反复出现的模式。第一静态默认凭据一旦贴在外壳上就再也收不回来了它不随密码轮换、不随固件升级失效生命周期等于设备寿命。第二把凭据从别的公开值派生出来无论算法多复杂本质上都是把秘密降级成公开信息复杂度只是让人一时看不出这层等价关系。第三为了改善体验而做的分段验证、分步反馈会把搜索空间从乘法变成加法每一段独立可破。这三条不是 WPS 独有的。今天去看各种设备的配网流程——二维码配网、声波配网、蓝牙辅助配网——都能看到同构的设计为了降低首次配置的门槛协议在短时间内打开一个宽松的通道通道里传递的凭据往往是长期有效的。区别只在于通道开了多久、凭据能不能轮换、失败反馈泄露了多少信息。6.2 一套可复现的自检清单在自己能控制的设备上我会按这个顺序过一遍先确认空口上还有没有 WSC IE再确认 Device Password ID 是不是 0x0000两个频段分别看然后确认后台那个 WPS 开关关掉之后上面的扫描结果有没有变化最后确认固件版本早期实现里 PIN 模式常常没有独立开关。这三步做完基本能判断一台设备是“真的关了”还是“看起来关了”。检查项通过标准不通过时的动作Beacon 中 WSC IE不存在关 PIN 模式或更换固件Device Password ID非 0x0000同上注意双频段分别检查后台开关与空口一致性关闭后扫描结果同步消失视为 UI 未生效按未关闭处理固件是否提供 PIN 独立开关提供无开关的老设备按不可信处理这套清单花不了十分钟但它挡住的是最容易被忽略的那类风险你以为关了实际没关。从那以后我每次碰任何带配网功能的设备都会先扫一遍空口再动配置先把“它自己说了什么”记下来再去看“界面说它是什么”。这个习惯救过我好几次包括一些自认为已经把开关关干净的场景。希望帮到你。本文还有配套的精品资源点击获取

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

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

免费获取报价 →
↑