Airkiss
目录 |
1 Overview
AirKiss 是微信提出的一种 WLAN 应用层协议,主要用于给无法交互的硬件设备进行网络配置,如 WiFi 插座,WiFi 灯泡等
其原理是将硬件设备的网卡置于监听模式 (monitor mode),又称为混杂模式 (promiscuous mode),获取到周围的 802.11 无线数据帧(俗称抓包),无线数据包中,有的字段加密,有点字段需要高操作权限,只有 Length 字段是可见的,利用这个字段我们就能约定一种传输数据的协议,从而在硬件设备初次进入环境时为其提供 WiFi 的帐号密码等信息。其联网方式类似于 TI 的 Smart Config。
802.11 是 IEEE 制定的无线局域网协议,802.11 以 802.3/802.2 的逻辑链路控制封装来携带 IP 封包:
Length 字段表示后面数据的长度,LLC 字段表示 LLC 头,SNAP (Subnet Access Protocol) 字段包括 3bytes 的厂商代码和 2bytes 的协议类型标识,DATA字段为负载
Airkiss上层在抓包之前先扫描附近的无线热点并记录其 ssid/crc 以及信道,从而使得 Airkiss 只用在这几个信道切换抓包。为了加快 Airkiss 进度,ssid 部分不再从 data 字段读取而只取其 crc (用 reserved 字段记录),上层应用将记录的 ssid/crc 进行对比,则可以获取目标的 ssid 信息并连接。连接后根据 Airkiss 协议,向 10000 端口广播 random 值通知发送端即可完成配置。
2 Airkiss Analysis
Run sudo ./airkiss wlan0, then scan the qrcode to trigger the airkiss process in WeChat (v6.7.3):
comcat@jackslab:/work/xwifi/airkiss$ sudo ./airkiss wlan0 scan all channels exec cmd: iw wlan0 set channel 1 exec cmd: iw wlan0 set channel 2 exec cmd: iw wlan0 set channel 3 exec cmd: iw wlan0 set channel 4 exec cmd: iw wlan0 set channel 5 exec cmd: iw wlan0 set channel 6 exec cmd: iw wlan0 set channel 7 exec cmd: iw wlan0 set channel 8 exec cmd: iw wlan0 set channel 9 exec cmd: iw wlan0 set channel 10 airkiss_recv_discover success base len:76 Lock channel in 10 airkiss_process_magic_code success total_len:22, ssid crc:be airkiss_process_prefix_code success pswd_len:10, pswd_lencrc:7e, need seq:3, seq map:7 [crc:67][index:0]:39,35,31,30; seq mapped:1 [crc:6f][index:1]:31,38,39,35; seq mapped:3 [crc:6b][index:3]:41,47,41,2d; seq mapped:3 [crc:29][index:4]:63,6f,6d,63; seq mapped:3 [crc:6f][index:1]:31,38,39,35; seq mapped:3 [crc:3c][index:2]:31,30,d4,47; seq mapped:7 User data is :39 35 31 32 31 38 39 35 31 32 d4 47 00 00 00 00 00 00 00 00 00 Airkiss completed. Result: ssid_crc:[be] key_len:[10] key:[9512189512] random:[0xd4] Sending random to broadcast..
3 Airkiss NFF Analysis
AirKiss NFF 即 weixin 近场发现技术(同一无线路由,扫描发现设备)
在此基础上,微信硬件平台推出了型号二维码,同一个类别/型号的设备都是贴一样的二维码,因此在设备生产过程中,不需要二维码与设备进行一一对应
设备主动定时(5s 一次)往 255.255.255.255 这个地址的 12476 端口,广播数据包:
comcat@jackslab:/work/xwifi/noduino-sdk/lib$ nc -u -l -p 12476 | xxd -g 1 0000000: fd 01 fe fc 00 10 00 01 00 00 00 7d 00 00 10 02 ...........}.... 0000010: 7b 22 64 65 76 69 63 65 49 6e 66 6f 22 3a 7b 22 {"deviceInfo":{" 0000020: 64 65 76 69 63 65 54 79 70 65 22 3a 22 67 68 5f deviceType":"gh_ 0000030: 39 35 66 61 65 31 62 61 36 66 61 30 22 2c 22 64 95fae1ba6fa0","d 0000040: 65 76 69 63 65 49 64 22 3a 22 67 68 5f 39 35 66 eviceId":"gh_95f 0000050: 61 65 31 62 61 36 66 61 30 5f 38 33 31 32 64 62 ae1ba6fa0_8312db 0000060: 31 63 37 34 61 36 64 39 37 64 30 34 30 36 33 66 1c74a6d97d04063f comcat@jackslab:/work/xwifi/noduino-sdk/lib$ nc -u -l -p 12476 ������}��{"deviceInfo":{"deviceType":"gh_95fae1ba6fa0","deviceId":"gh_95fae1ba6fa0_8312db1c74a6d97d04063fb88d9a8e47"}}
如上,监听 12476 这个 UDP 端口就知道,其广播数据含有两个关键的数据:
- deviceType: gh_95fae1ba6fa0
- deviceId: gh_95fae1ba6fa0_8312db1c74a6d97d04063fb88d9a8e47
这个 deviceType 实际就是公众号的原始ID: gh_95fae1ba6fa0
微信客户端在收到这个 UDP 广播包后,会用得到的 deviceType 和 deviceId 去对应公众号的数据库里查找,看是否有这个设备存在
如果存在,则也往 12476 这个端口发一个,确认包,设备收到后,再回一个响应包,则完成过程
传统微信设备生产流程是:
- 厂家自己生成 device id,并向公众平台申请带参二维码,有多少个 device id 就需要多少个带参二维码
- 厂家后台记录 device id 和带参二维码的对应关系,并在设备出厂时,一一对应地贴在设备包装盒或者说明书上
- 用户扫描带参二维码,微信客户端会把二维码的参数通过公众平台的后台传给厂家后台
- 厂家后台记录二维码的参数和用户 openid 完成设备绑定
由此过程可发现,新思路和传统方法的差别在:
- 厂家直接向公众平台申请 device id,自己后台登记该 device id 即可,设备出厂时所有设备使用相同的二维码(微信型号码)
- 微信客户端扫描可直接进入监听 UDP 端口的二维码(微信型号码),直接进入监听状态
- 设备主动向特定端口广播自己需要关联的公众号 (deviceType) 和设备 ID (deviceId)
- 微信客户端会用得到的 deviceType 和 deviceId 去对应公众号的数据库里查找,设备存在(厂家用 deviceId 做过设备授权)则进入绑定界面
- 用户点绑定后,微信后台会给厂商的后台一个如下消息:
<xml> <ToUserName><![CDATA[gh_95fae1ba6fa0]]></ToUserName> <FromUserName><![CDATA[o7okrt5x5y0QF3ZoORfhBs_XM4I8]]></FromUserName> <CreateTime>1447343815</CreateTime> <MsgType><![CDATA[device_event]]></MsgType> <Event><![CDATA[bind]]></Event> <DeviceType><![CDATA[gh_95fae1ba6fa0]]></DeviceType> <DeviceID><![CDATA[gh_95fae1ba6fa0_8312db1c74a6d97d04063fb88d9a8e47]]></DeviceID> <Content><![CDATA[]]></Content> <SessionID>0</SessionID> <OpenID><![CDATA[o7okrt5x5y0QF3ZoORfhBs_XM4I8]]></OpenID> </xml>
厂商的后台只要解析后,将用户 open id 和 device id 的对应关系登记入数据库,即可完成绑定过程,再也无需一一对应地人肉贴带参二维码了
厂家生产时,还是要把从 weixin 申请的 deviceId 写入设备 flash/eeprom 上
- 注意:已经绑定的设备,微信客户端在查找设备时会自动忽略
4 Reference
- Airkss技术实现方案
- How does TI CC3000 wifi smart config work?
- https://github.com/pannzh/Airkiss
- ESP8266_SmartConfig
- ESP8266 AirKiss NFF
- 型号二维码指南:http://iot.weixin.qq.com/document-7_3.html
- 微信设备授权新接口:http://iot.weixin.qq.com/document-2_11.html
- “型号码”帮助企业简化设备生产