从Android视角全面解读Wifi Easy Connect

前言:

Wifi Easy Connect(下文简称WEC)是Wi-Fi Alliance推出一种wifi信息简单传输和设置的一种新的技术手段。使用WEC可以简单、高效的将wifi信息通过A设备分享给B设备。

实用场景:

场景一:啊强和啊珍是一对好朋友,有一天,啊强跟阿珍说自己家的猫会后空翻,想请啊珍来家里欣赏一下,阿珍欣然答应了。来到阿强家,阿珍想要连一下啊强家的wifi,通常的情况下,啊强只需要告诉阿珍自己家的wifi名称和密码,阿珍就可以自己连接Wi-Fi了。但是此刻啊强却忘记了自己家的wifi密码,那么他就可以通过WEC的方式,将自己手机的wifi信息生成一个二维码,阿珍只需要扫描一下这个二维码即可连接到对应的wifi信息了。

场景二:啊强知道阿珍很喜欢听音乐,就买了一个wifi音箱送给阿珍。wifi音箱嘛,肯定是需要连接Wi-Fi的,啊强告诉阿珍,只需要拿手机扫描一下音箱上的二维码,就可以让手机连接wifi信息共享给音箱了。

从上面两个场景就可以看出,wifi的信息共享对于用户来说十分的方便,扫描一下就可以给设备设置手机连接的wifi信息了。

在WEC之前厂商的方案:

其实在WEC出来之前,各个厂商都有一套自己的wifi分享的方式,

  • AP模式:当设备处于待配网的状态的时候,就让设备向外发送一个热点,然后让手机连接热点之后,通过tcp的方式向设备发送wifi信息。
  • Smart Config:通过数据帧中未加密的组播字段和长度字段来传输编码后的网络配置信息。(上海交通大学有过一次加密的分享会,来阐述Smart Config存在的安全隐患 【传送门】
  • udp组播+UDP单播:先通过UPD的组播发现目标设备,然后通过UDP单播进行网路配置。

Wifi Alliance的Wifi Easy Connect

上面的几种方式,均存在安全性和统一性的缺陷。为了解决上述两个问题,Wifi Alliance于2018年推出了Wifi Easy Connect的wifi信息分享方案。Wifi Alliance的WEC使用DPP的数据传输协议。DPP (Device Provisioning Protocol) 是 Wi-Fi Alliance 开发的一种安全协议,用于在设备之间进行安全的初始设置和管理。DPP 通过多种机制来保证数据加密的安全性:

  1. 公钥加密:DPP 使用公钥加密技术来确保数据的安全性。设备在初始设置期间会交换公钥,然后使用它们来加密和解密信息。只有拥有相应私钥的设备才能解密使用公钥加密的信息。
  2. 身份验证:DPP 使用基于公钥的身份验证机制来确认设备的身份。这种机制可以防止中间人攻击,因为只有真正的设备才能成功地通过身份验证。
  3. 完整性检查:DPP 使用加密哈希函数来确保数据的完整性。这意味着任何对数据的更改都会被立即检测到。
  4. 密钥派生:DPP 使用安全的密钥派生函数来生成新的加密密钥。这些密钥用于保护设备间的通信,并且每次都会生成新的密钥,以防止密钥被复用。
  5. 前向保密:即使在设备的私钥被泄露后,DPP 也能保护之前的通信不被解密。这是通过在每次通信时都生成新的临时密钥来实现的。 通过这些机制,DPP 可以在设备之间创建一个安全的通信渠道,从而确保数据的加密和安全性。

那么WEC是如何进行wifi信息的分享的。这里我们先简要说明以下几个概念:

  1. Configurator:作为配置网络的控制器,将不同的其他设备连接入无线局域网,也用于配置AP(一般是带有丰富的草操作界面的设备,例如:手机,平板电脑等)
  2. Enrollee:需要接入无线局域网的设备(例如:家里使用的wifi门锁、wifi音箱,当然也可以是其他手机或者平板电脑)
  3. Initiator:在DPP authentication 过程中的发起者(通常这个和Configurator是同一个设备)
  4. Responser:对应Initiator,在DPP authentication过程中的回复者(通常这个和Enrollee是同一个设备)
  5. Connector:Configurator发放Connector给Enrollee,Enrollee使用Connector向AP发起网络连接。(这个就是wifi信息的包装)

WEC流程简介

下面我们来看一下WEC的一些配置过程(以下提及到的设备都支持WAP3,支持了WAP3肯定是支持DPP协议的)。

sequenceDiagram Configurator(手机)->>Enrollee(终端设备): 扫描DPP二维码 Enrollee(终端设备)->>Configurator(手机): 返回终端设备信息 Configurator(手机)->>Configurator(手机): 解析DPP二维码。

密钥管理类型、
终端设备mac地址、
设备支持的公钥、
设备支持的无线通信频道、
设备名称等其他设备信息
) Configurator(手机)->>Enrollee(终端设备): 将手机的公钥通过上述的无线通信频道个mac地址,
使用设备公钥进行加密发送给终端设备 Enrollee(终端设备)->>Enrollee(终端设备): 通过私钥解析出手机的公钥
(至此,双方都有了对方的公钥) Enrollee(终端设备)->>Configurator(手机): 请求wifi信息 Configurator(手机)->>Enrollee(终端设备): 发送wifi信息 Enrollee(终端设备)->>Enrollee(终端设备): 解析并尝试连接wifi Enrollee(终端设备)->>Configurator(手机): 返回连接结果

附上一张DPP过程(本次DPP的过程不做详细说明):

官方WEC过程说明:

第一步:假设我们的路由器此时已经配置好了。这个时候,我们拿出手机来,通过扫描路由器机身上的二维码,注意,这个二维码是其实就是一个DPP的Uri。其中DPP的Uri格式如下:

xml 复制代码
DPP:<key management designator>;<mac address>;<public key>;<channel>;<information>

每个部分的详细说明如下:

  • key management designator:此部分指示使用的密钥管理类型,例如,"dpp" 或 "psk"。
  • mac address:此部分是设备的 MAC 地址。
  • public key:此部分是设备的公钥,用于在设备之间建立安全的通信通道。
  • channel :此部分指示设备通信的无线频道。(重点,后续的数据传输频道就是通过这个channel进行的)
  • information:此部分包含其他可能需要的信息,例如设备的名称或其他标识符。

手机扫描到这个DPP生成的二维码之后,解析出上述的信息,这个时候,手机就可以通过DPP协议,使用上述的channel频道建立和mac address建立通信通道,然后生成自己的公要key2,然后使用上述的公钥key,将自己的key2进行加密发送给路由器,路由器收到之后解密得到key2,然后将wifi信息(ssid和psw)通过key2加密之后发送给手机,手机进行解密之后,就可以成功拿到wifi信息进行wifi设置了。(其实这里已经是一个完整的WEC过程了),此时手机就可以作为网络的Configurator

第二步:完成第一步之后,手机就可以作为整个WEC里面的Configurator,我们通过手机去扫描终端设备上的DPP QR,就可以跟终端设备建立连接,然后通过DPP的方式分享自己的wifi信息给到终端设备。

最后,终端设备可以完整的连入我们家庭的网络里面。

Android如何使用?

framework支持WEC

首先,根据官方的描述,Google已经在android-10(API SDK Version = 29)对WEC进行支持了。

如果你是一位android系统的framework层的开发者,要想你的android系统支持WEC,首先实现 Android 开源项目 (AOSP) 中提供的客户端接口。根据已实现的接口,相应位置如下:

如需支持 DPP,必须具备以下几项:

APP应用层支持WEC

如果你是一位APP的开发人员,你可以参考下方的代码去对你的应用支持WEC。

权限:

ini 复制代码
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

其中位置权限是动态权限,需要动态申请。

获取wifiManager实例:

kotlin 复制代码
private val wifiManager : WifiManager by lazy {
    getSystemService(WIFI_SERVICE) as WifiManager
}

判断手机是否支持WEC

ini 复制代码
val easyConnectSupported = wifiManager?.isEasyConnectSupported ?: false

准备DPP Uri和Intent

ini 复制代码
val dppString = "DPP:C:81/6;M:fc029635a382;I:22061218C;V:2;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgACVo/Hp3P/Dg7uVt/tkkTnzAkud5lpeod5a2KIqDxqVgk=;;"
val wecIntent = Intent().apply {
    action = ACTION_PROCESS_WIFI_EASY_CONNECT_URI,
    data = Uri.parse(dppString)
}

跳转系统WEC页面

php 复制代码
if(easyConnectSupported){
    if (wecIntent.resolveActivity(packageManager) != null){
        startActivityForResult(myIntent,REQUEST_CODE)
    }else{
        // 找不到对应的activity设置页面
        throw Exception("find no activity to support Wifi Easy Connect!")
    }
} else{
    // todo 当前设备不支持wifi easy connect
}

处理结果

kotlin 复制代码
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (requestCode == REQUEST_CODE) {
        if (resultCode == Activity.RESULT_OK) {
            // Wi-Fi Easy Connect 配置成功
        } else if (resultCode == Activity.RESULT_CANCELED) {
            // Wi-Fi Easy Connect 配置失败
            val errorCode = data?.getIntExtra(WifiManager.EXTRA_EASY_CONNECT_ERROR_CODE, 0)
            // errorCode 是 EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_* 中的一个
        }
    }
}

这里附上一张vivo支持的WEC的系统界面图

QA:

Q:若要支持WEC,是否路由器、手机、子设备均要支持WEC呢? A:这个看具体的使用场景。假设,我们的诉求是希望手机连接路由器的时候,不要输入ssid和psd,那么路由器也是需要支持的,但是如果在对手机设置wifi信息的时候,可以使用ssid和psd的话,而只是对子设备设置wifi信息的时候,那么路由器可以不支持WEC,因为后续的子设备设置wifi,本质上还是通过交换信息之后获取了ssid和psd的过程。只不过路由器支持的话,安全级别会更高(使用的WAP3)。

Q:是否所有的Android 10以上的手机都支持WEC? A:这个具体要看机型的厂家对WEC的支持。判断依据可以见上述android应用支持WEC。

Q:华为的鸿蒙支持吗? A:目前我就使用了华为p40pro,是鸿蒙4.0的系统,目前是不支持的。

总结:

Wi-Fi CERTIFIED Easy Connect™降低了设备与Wi-Fi®网络连接的复杂性,提升了用户体验,同时采用了最高级别的安全标准。Wi-Fi Easy Connect™引入了标准化机制,以简化Wi-Fi设备的配置。现在,可以非常简便地配置设备,包括那些没有丰富用户界面的设备,通过扫描产品QR码、NFC标签或从云下载设备信息,就可实现与Wi-Fi网络的零接触式连接。

Wi-Fi Easy Connect为Wi-Fi网络管理提供了简便性、一致性和灵活性。

  • 使用简便直观;设置新设备时无需阅读冗长的说明。
  • 无需记住密码并将密码输入到接受配置的设备中。
  • 可使用电子或打印的QR码、NFC标签或从云下载的设备信息。
  • 通过使用QR码实现几乎零接触的配置。
  • 通过从云下载设备信息实现真正的零接触配置。

在如今IOT快速发展的时候,WEC肯定能帮助我们更加高效的提升智能设备接入的效率,简化我们的步骤。如果文章有错误的话,麻烦同学指正哈~

相关推荐
帅得不敢出门10 小时前
安卓设备adb执行AT指令控制电话卡
android·adb·sim卡·at指令·电话卡
我又来搬代码了12 小时前
【Android】使用productFlavors构建多个变体
android
德育处主任13 小时前
Mac和安卓手机互传文件(ADB)
android·macos
芦半山13 小时前
Android“引用们”的底层原理
android·java
迃-幵14 小时前
力扣:225 用队列实现栈
android·javascript·leetcode
大风起兮云飞扬丶14 小时前
Android——从相机/相册获取图片
android
Rverdoser14 小时前
Android Studio 多工程公用module引用
android·ide·android studio
aaajj15 小时前
[Android]从FLAG_SECURE禁止截屏看surface
android
@OuYang15 小时前
android10 蓝牙(二)配对源码解析
android
Liknana15 小时前
Android 网易游戏面经
android·面试