Wi-Fi EAP网络验证过程与Android平台拓展实例(一)

文章参考的是Android 7.1的源码
本文主要研究EAP类型网络的身份验证过程,从而简化Android平台EAP类型网络的身份验证过程。


1. 什么是EAP

  Extensible Authentication Protocol,简称EAP,是一种支持多种验证方式的协议框架,EAP通常运行在链路层例如PPP和IEEE 802。EAP协议是IEEE 802.1x认证机制的核心,它将实现细节交由附属的EAP Method协议完成,如何选取EAP method由认证系统特征决定,这样实现了EAP的扩展性及灵活性(摘自”百度百科”)。这篇文章主要描述的场景是基于Radius服务器的EAP身份认证方式。
  了解本文前,如果您的身边没有EAP网络环境,可以通过路由器和Radius进行搭建。

2. IOS和Android对EAP支持的区别

  下图分别是IOS(左图)和Android(右图)连接EAP-TTLS加密方式网络的设置界面:
  Wi-Fi EAP网络验证过程与Android平台拓展实例(一)_第1张图片
  从上图看,IOS系统中,只需要用户输入用户名和密码,但是在Android系统上,则需要用户指定具体的EAP方法(默认使用PEAP),如果选择的EAP方法与AP认证服务器指定的不对应,则无论用户名和密码正确与否都会验证失败。
  我们知道,在未开始连接前,设备是只知道这个AP是EAP加密方式,但不知道具体的EAP方法。那为什么IOS都没有选择具体EAP方法就可以连上这个TTLS加密方式的网络呢?而且,将AP的EAP方法改为PEAP,IOS同样可以连上,这点很奇怪!需要刨根问题追究缘由,则需要抓出认证过程中,IOS与认证服务器的交互包。
  
3. IOS EAP认证过程探究

  设定Radius EAP方法为TTLS,开启Radius服务:

xyzc@xyzc-ul:~$ sudo radiusd -X
FreeRADIUS Version 3.0.16
Copyright (C) 1999-2017 The FreeRADIUS server project and contributors
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
...
Listening on auth address * port 1812 bound to server default
Listening on acct address * port 1813 bound to server default
Listening on auth address :: port 1812 bound to server default
Listening on acct address :: port 1813 bound to server default
Listening on auth address 127.0.0.1 port 18120 bound to server inner-tunnel
Listening on proxy address * port 43060
Listening on proxy address :: port 48623
Ready to process requests

  在搭建了Radius服务的主机上开始抓取tcpdump,并使用IPhone开始连接

xyzc@xyzc-ul:~/ulangch/eap$ sudo tcpdump -i any -w tcpdump-ios.pcap
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes

  实验完成后使用wireshark分析IPhone连接过程中抓取Radius服务所在主机的tcpdump。
  如下为tcpdump抓取的Radius协议数据包,这部分即代表了认证过程,192.168.1.1192.168.1.100分别代表了路由器网关IP和Radius服务主机IP。

179 2018-05-14 15:43:19.055587  192.168.1.1 192.168.1.100   RADIUS  201 Access-Request(1) (id=0, l=157)
180 2018-05-14 15:43:19.056882  192.168.1.100   192.168.1.1 RADIUS  124 Access-Challenge(11) (id=0, l=80)
192 2018-05-14 15:43:19.155723  192.168.1.1 192.168.1.100   RADIUS  215 Access-Request(1) (id=1, l=171)
193 2018-05-14 15:43:19.157221  192.168.1.100   192.168.1.1 RADIUS  108 Access-Challenge(11) (id=1, l=64)
195 2018-05-14 15:43:19.189098  192.168.1.1 192.168.1.100   RADIUS  368 Access-Request(1) (id=2, l=324)
196 2018-05-14 15:43:19.193632  192.168.1.100   192.168.1.1 RADIUS  1124    Access-Challenge(11) (id=2, l=1080)
197 2018-05-14 15:43:19.272446  192.168.1.1 192.168.1.100   RADIUS  213 Access-Request(1) (id=3, l=169)
198 2018-05-14 15:43:19.273774  192.168.1.100   192.168.1.1 RADIUS  1124    Access-Challenge(11) (id=3, l=1080)
199 2018-05-14 15:43:19.305511  192.168.1.1 192.168.1.100   RADIUS  213 Access-Request(1) (id=4, l=169)
200 2018-05-14 15:43:19.306681  192.168.1.100   192.168.1.1 RADIUS  781 Access-Challenge(11) (id=4, l=737)
203 2018-05-14 15:43:20.855671  192.168.1.1 192.168.1.100   RADIUS  343 Access-Request(1) (id=5, l=299)
204 2018-05-14 15:43:20.857646  192.168.1.100   192.168.1.1 RADIUS  163 Access-Challenge(11) (id=5, l=119)
205 2018-05-14 15:43:20.922293  192.168.1.1 192.168.1.100   RADIUS  266 Access-Request(1) (id=6, l=222)
206 2018-05-14 15:43:20.924311  192.168.1.100   192.168.1.1 RADIUS  173 Access-Challenge(11) (id=6, l=129)
207 2018-05-14 15:43:20.955585  192.168.1.1 192.168.1.100   RADIUS  286 Access-Request(1) (id=7, l=242)
208 2018-05-14 15:43:20.958304  192.168.1.100   192.168.1.1 RADIUS  213 Access-Accept(2) (id=7, l=169)

  直接从192帧开始分析:

192 2018-05-14 15:43:19.155723  192.168.1.1 192.168.1.100   RADIUS  215 Access-Request(1) (id=1, l=171)

RADIUS Protocol
    Code: Access-Request (1)
    ...
    Attribute Value Pairs
        AVP: l=9 t=User-Name(1): ulangch  /** ulangch是我们输入的用户名*/
        ...
        AVP: l=31 t=Called-Station-Id(30): 80-89-17-3D-E0-10:TPLINK-TTLS /** TPLINK-TTLS 是路由器名称*/
        ...
        AVP: l=10 t=EAP-Message(79) Last Segment[1]
            ...
            Extensible Authentication Protocol /** EAP协议定义的数据*/
                Code: Response (2)
                Id: 1
                Length: 8 /** 注意这里的长度是8*/
                Type: Legacy Nak (Response Only) (3)
                Desired Auth Type: Protected EAP (EAP-PEAP) (25) /** 这里指定了期望认证类型为EAP-PEAP*/
        ...

  第192帧是STA通过AP包装和转发给Radius服务器的一帧数据,Desired Auth Type: Protected EAP (EAP-PEAP) (25) 表明希望的加密方式,这与我们上面设定的EAP-TTLS不符合,那是否就会被Reject呢?下面继续看Radius的回应(第193帧):

193 2018-05-14 15:43:19.157221  192.168.1.100   192.168.1.1 RADIUS  108 Access-Challenge(11) (id=1, l=64)

RADIUS Protocol
    Code: Access-Challenge (11)
    ...
    Attribute Value Pairs
        AVP: l=8 t=EAP-Message(79) Last Segment[1]
            AVP Type: 79
            AVP Length: 8
            EAP fragment: 010200061520
            Extensible Authentication Protocol /** EAP协议定义的数据*/
                Code: Request (1) 
                Id: 2
                Length: 6
                Type: Tunneled TLS EAP (EAP-TTLS) (21) /** 表明支持的认证方式是TTLS*/
                EAP-TLS Flags: 0x20
        ...

  第193帧表明,在STA表明自己期望的EAP方法后,Radius发出方法是TTLS的认证挑战帧,Type: Tunneled TLS EAP (EAP-TTLS) (21) 表明认证服务器会采用TTLS进行接下来的认证。这样的响应是不容质疑的,毕竟Radius目前被设定为只支持该类型,继续看下一帧IPhone的响应(第195帧):
  

195 2018-05-14 15:43:19.189098  192.168.1.1 192.168.1.100   RADIUS  368 Access-Request(1) (id=2, l=324)

RADIUS Protocol
    Code: Access-Request (1)
    ...
    Attribute Value Pairs
        AVP: l=9 t=User-Name(1): ulangch
        ...
        AVP: l=163 t=EAP-Message(79) Last Segment[1]
            AVP Type: 79
            AVP Length: 163
            EAP fragment: 020200a115800000009716030100920100008e03035af93e...
            Extensible Authentication Protocol /** EAP协议定义的数据*/
                Code: Response (2)
                Id: 2
                Length: 161
                Type: Tunneled TLS EAP (EAP-TTLS) (21) /** 使用TTLS进行认证*/
                EAP-TLS Flags: 0x80
                EAP-TLS Length: 151
                Secure Sockets Layer
                    TLSv1.2 Record Layer: Handshake Protocol: Client Hello /** Client Hello,申请进行握手,建立连接以便于接下来的数据传输*/
                        Content Type: Handshake (22)
                        Version: TLS 1.0 (0x0301)
                        Length: 146
                        Handshake Protocol: Client Hello
        ...

  接下来就是握手交换秘钥的过程以及最终的身份和密码认证,直到第208帧,Radius服务认证通过:

208 2018-05-14 15:43:20.958304  192.168.1.100   192.168.1.1 RADIUS  213 Access-Accept(2) (id=7, l=169)

RADIUS Protocol
    Code: Access-Accept (2)
    Packet identifier: 0x7 (7)
    Length: 169
    Authenticator: ed1a896e29b2222b21cffcc5ad0c6b70
    Attribute Value Pairs
        AVP: l=58 t=Vendor-Specific(26) v=Microsoft(311)
        AVP: l=58 t=Vendor-Specific(26) v=Microsoft(311)
        AVP: l=6 t=EAP-Message(79) Last Segment[1]
            AVP Type: 79
            AVP Length: 6
            EAP fragment: 03070004
            Extensible Authentication Protocol /** EAP协议定义的数据*/
                Code: Success (3) /** 认证通过*/
                Id: 7
                Length: 4
        AVP: l=18 t=Message-Authenticator(80): de70821ccbfa78162d71f9e7e30c1cdf
        AVP: l=9 t=User-Name(1): ulangch

  从上面可以看出,IPhone和认证服务器通过AP包装和转发身份信息,EAP方法,Hash后的密码,最终成功完成认证,那么Android系统在连接这个AP时会出现什么情况呢,请看下节。

4. Android EAP认证过程探究

  与上面测试IOS连接TPLINK-TTLS的过程相似,Android设备选择PEAP的认证方式,身份和密码均与上面IOS的测试相同,主要分析Android设备连接EAP类型AP的认证过程。下面是Radius服务主机抓取的tcpdump:

38  2018-05-14 17:28:56.177797  192.168.1.1 192.168.1.100   RADIUS  201 Access-Request(1) (id=46, l=157)
39  2018-05-14 17:28:56.179016  192.168.1.100   192.168.1.1 RADIUS  124 Access-Challenge(11) (id=46, l=80)
40  2018-05-14 17:28:56.210892  192.168.1.1 192.168.1.100   RADIUS  213 Access-Request(1) (id=47, l=169)
43  2018-05-14 17:28:57.213237  192.168.1.100   192.168.1.1 RADIUS  88  Access-Reject(3) (id=47, l=44)

  从上面第43帧就可以看出认证失败了,依葫芦画瓢,开始逐帧分析(跳过前两帧,从第40帧开始):

40  2018-05-14 17:28:56.210892  192.168.1.1 192.168.1.100   RADIUS  213 Access-Request(1) (id=47, l=169)

RADIUS Protocol
    Code: Access-Request (1)
    ...
    Attribute Value Pairs
        AVP: l=9 t=User-Name(1): ulangch
        ...
        AVP: l=8 t=EAP-Message(79) Last Segment[1]
            AVP Type: 79
            AVP Length: 8
            EAP fragment: 020100060319
            Extensible Authentication Protocol
                Code: Response (2)
                Id: 1
                Length: 6 /** 注意这里的长度是6*/
                Type: Legacy Nak (Response Only) (3)
                Desired Auth Type: Protected EAP (EAP-PEAP) (25) /** 期望的加密类型是PEAP*/
        AVP: l=18 t=State(24): 2cd24e092cd34a78fd556806a4506d3c
        AVP: l=18 t=Message-Authenticator(80): 0476c2371dbd53be8bd91bc8d350af8f

  第40帧看起来和上面测试IOS时的192帧好像没什么区别,但是为什么迎来的不是Access Challenge而是Access Reject呢(第43帧):

43  2018-05-14 17:28:57.213237  192.168.1.100   192.168.1.1 RADIUS  88  Access-Reject(3) (id=47, l=44)

RADIUS Protocol
    Code: Access-Reject (3)
    ...
    Attribute Value Pairs
        AVP: l=6 t=EAP-Message(79) Last Segment[1]
            AVP Type: 79
            AVP Length: 6
            EAP fragment: 04010004
            Extensible Authentication Protocol
                Code: Failure (4)
                Id: 1
                Length: 4
        AVP: l=18 t=Message-Authenticator(80): ffc562cb3a29579e8b464e5767bdfad8

  这样看起来就非常奇怪了,IOS和Android发给Radius服务表明自己的Desired Auth Type都是PEAP,为什么得到的却是不一样的回应呢???
  
5. 揭晓神秘面纱

  注意我上面的注释,在IOS的第192帧和Android的第40帧中,有一个微小的区别:

/** IOS*/
Extensible Authentication Protocol /** EAP协议定义的数据*/
    Code: Response (2)
    Id: 1
    Length: 8 /** 注意这里的长度是8*/
    Type: Legacy Nak (Response Only) (3)
    Desired Auth Type: Protected EAP (EAP-PEAP) (25) /** 期望认证类型为是PEAP*/

/** Android*/
Extensible Authentication Protocol
    Code: Response (2)
    Id: 1
    Length: 6 /** 注意这里的长度是6*/
    Type: Legacy Nak (Response Only) (3)
    Desired Auth Type: Protected EAP (EAP-PEAP) (25) /** 期望的加密类型是PEAP*/

  看起来都相同,为什么长度还不一样呢,这里面是否有什么蹊跷?还是需要看下这两帧的字节流:

/** IOS*/
02 01 00 08 03 19 15 2b

/** Android*/
02 01 00 06 03 19

  看到区别没有?IOS这一帧的EAP协议数据里多了两个字节!!!下面逐个字节分析一下:

02:             对应类型,Request 还是 Response
01:             对应Id
00 08:          两个字节对应EAP协议头长度
03:             对应Type
19 15 2b:       十进制分别是25 21 27,代表了3种EAP方法!

  所以不难想象了,IOS中指定了3种EAP方法,分别是十进制的252127,筛了一下freeradius的代码,发现这三个数字分别代表了PEAPTTLSMAKE。所以造成差异的原因就是IOS请求方发送了3种EAP方法供给认证服务进行选择并且其中包含了TTLS,而Android则只指定了一种,且不是TTLS,所以才会被Reject!造成困惑的罪魁祸首就是wireshark只识别出了PEAP!
  
  下面可以总结一下EAP认证流程了(部分流程没有在上述tcpdump中体现,可以查看802.11协议或者抓取sniffer来更详细了解EAP认证过程):

  • STA发送EAPoL-Start帧来初始化EAP认证过程
  • AP发送EAP-Request来请求请求方的的身份
  • STA发送携带身份信息的EAP-Response,其AVP中携带User-Name和支持的Auth Type
  • AP将EAP-Response帧封装在RADIUS数据包中转发给认证服务器
  • 认证服务器检查身份信息,确定Auth Type并将Access Challenge帧封装在RADIUS数据包中
  • AP以802.11 EAP帧形式转发Access Challenge给STA
  • STA将密码经过加密后以802.11 EAP帧形式发送给AP
  • AP将加密密码封装成RADIUS数据包转发给认证服务器
  • 认证服务器将保存的密码经过相同的加密方式加密后与AP转发的加密密码对比,返回一个包装了认证结果的RADIUS数据包
  • AP将认证结果以802.11 EAP帧形式发送给STA,并完成认证过程

IOS和Android在EAP网络认证过程上最重要的区别就是IOS的Auth Type中包含了3中EAP方法,而Android只包含了一种,且Radius服务器不支持该EAP方法。

你可能感兴趣的:(WiFi,wpa_supplicant)