18、安全机制:WPA2/WPA3 支持、证书管理、企业级认证(EAP)
Wi-Fi 安全,说白了就是解决两个问题:你是谁 和 数据有没有被偷看。
我在做 Android Wi-Fi 开发的早期,总觉得安全这块是协议栈的事,应用层不用太操心。直到有一次,客户反馈说他们的企业路由器连不上,日志里全是 EAP 认证失败的报错……嗯,从那以后,我再也不敢轻视安全机制了。
18.1 WPA2 与 WPA3:从兼容到演进
WPA2 是过去十年的主流,WPA3 是新一代标准。Android 从 10 开始原生支持 WPA3,但实际落地时,你会发现很多设备还在用 WPA2。
核心区别:
- WPA2:使用 4 次握手(4-Way Handshake),预共享密钥(PSK)容易受到字典攻击。
- WPA3:引入 SAE(Simultaneous Authentication of Equals),也就是 Dragonfly 握手,抵抗离线字典攻击。
我个人习惯在代码里这样判断当前网络的安全类型:
// 获取当前连接的网络安全能力
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int securityType = wifiInfo.getSecurityType();
switch (securityType) {
case WifiInfo.SECURITY_TYPE_PSK:
// WPA2-Personal
break;
case WifiInfo.SECURITY_TYPE_SAE:
// WPA3-Personal
break;
case WifiInfo.SECURITY_TYPE_EAP:
// 企业级认证
break;
}
你想想看,如果设备不支持 WPA3,你硬要配置 SAE 参数,连接就会失败。所以,先查询能力,再配置网络,这是基本素养。
避坑指南:我曾经在 Android 11 上遇到一个 bug——某些旧款路由器虽然广播了 WPA3 能力,但实际握手时只支持 WPA2。解决方案是:在连接失败后,降级尝试 WPA2 配置。
18.2 证书管理:信任链的基石
企业级认证离不开证书。Android 使用 KeyStore 系统来管理证书和私钥。说白了,这就是一个安全容器,应用不能直接读取私钥内容,只能通过 API 使用它。
我建议你把证书管理分为三个层次:
- 系统证书:预装在 /system/etc/security/cacerts/ 下,用于验证服务器身份。
- 用户证书:用户通过设置安装的证书,存储在 KeyStore 中。
- 应用证书:应用自己生成的客户端证书,用于 EAP-TLS 认证。
安装一个 CA 证书的典型代码:
// 通过 Intent 安装证书
Intent installIntent = KeyChain.createInstallIntent();
byte[] certBytes = ...; // 从文件或网络读取
installIntent.putExtra(KeyChain.EXTRA_CERTIFICATE, certBytes);
startActivityForResult(installIntent, REQUEST_INSTALL_CERT);
嗯,这里要注意:安装证书需要用户交互,你不能静默安装。这是 Android 的安全设计,防止恶意应用偷偷植入根证书。
警告:千万不要把私钥硬编码在代码里。我曾经见过一个项目,把客户端证书的私钥写在 strings.xml 中……结果被反编译后,整个企业网络都暴露了。
18.3 企业级认证(EAP):不止是输入用户名密码
EAP(Extensible Authentication Protocol)是一个框架,不是单一协议。Android 支持多种 EAP 方法,我挑几个常用的说说:
| EAP 方法 | 认证方式 | 安全性 | 典型场景 |
|---|---|---|---|
| EAP-TLS | 客户端证书 + 服务器证书 | 最高 | 金融、政府内网 |
| EAP-TTLS | 服务器证书 + 用户名/密码(隧道内) | 高 | 中型企业 |
| PEAP | 服务器证书 + MSCHAPv2 | 中高 | 大多数企业 Wi-Fi |
| EAP-SIM/AKA | SIM 卡认证 | 高 | 运营商热点 |
配置一个 PEAP 企业网络的代码示例:
WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2);
enterpriseConfig.setIdentity("user@domain.com");
enterpriseConfig.setPassword("your-password");
// 设置 CA 证书
enterpriseConfig.setCaCertificate(caCert);
WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"corp-wifi\"";
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
config.enterpriseConfig = enterpriseConfig;
wifiManager.addNetwork(config);
为什么需要设置 CA 证书?因为如果不验证服务器身份,攻击者可以伪造一个假的 RADIUS 服务器,截获你的用户名和密码。这就是所谓的 中间人攻击。
我的经验:在配置 EAP-TLS 时,客户端证书的私钥必须标记为 KeyProperties.PURPOSE_SIGN,否则握手时会报错。我曾经在这个坑里卡了两天,最后发现是 KeyGenParameterSpec 的用途没设对。
18.4 安全机制的整体流程
为了让你更直观地理解,我画了一张图,展示从扫描到连接的安全决策路径:
从图中你可以看到,安全决策不是一条直线。WPA2/WPA3 走的是密钥派生路径,EAP 走的是证书验证路径,而开放网络……嗯,我建议你直接屏蔽掉。
18.5 实战中的几个关键点
- 证书过期处理:企业证书通常有有效期。我建议在连接前检查证书的有效期,如果即将过期,提前提示用户更新。
- EAP 方法协商:有些 RADIUS 服务器会要求特定的 EAP 方法。如果配置不对,连接会一直卡在 "正在获取 IP 地址" 阶段。
- 隐私保护:WPA3 支持 Opportunistic Wireless Encryption(OWE),即使没有密码也能加密传输。这在公共热点场景下很有用。
小技巧:调试企业级认证时,可以开启 Wi-Fi 的详细日志:adb shell dumpsys wifi 然后搜索 "EAP" 或 "supplicant"。我曾经靠这个命令定位到一个证书链不完整的问题。
安全机制这块,说白了就是「信任」两个字。你信任谁,用什么方式证明信任,数据怎么保护。Android 框架把这些都封装好了,但你要理解背后的原理,才能在遇到问题时快速定位。
公众号:蓝海资料掘金营,微信deep3321