Wi-Fi 新标准 WPA3 蜻蜓 (Dragonfly) 密钥交换协议分析
在2018年1月8日美国拉斯维加斯的国际消费电子展(CES)上,Wi-Fi联盟发布了最新的WPA3加密协议,作为WPA2技术的的后续版本,并在2018年6月26日,WiFi联盟宣布WPA3协议已最终完成。与WPA3相关的最核心的文档为RFC7664,其中描述的是WPA3中最大的改进,就是将原来的四次握手协议换成了新的“蜻蜓秘钥交换协议”(Dragonfly Key Exchange),该协议将认证和秘钥交换两个功能合成于一个协议。号称可以解决WPA2中未解决的几个安全问题:
1.离线密码破解——获得WPA2的四次握手包即可进行离线字典攻击,破解无线密码。
2.转发安全(Forward Secracy)——已知4次握手和无线密码的情况下,可以解密目标的所有通信流量。
3.KRACK等其他已知攻击方法。
由于WPA3还尚未普及,想来目前无论公众还是相关研究人员对WPA3的协议的实施细节所知应该并不多,所以笔者在仔细阅读RFC7664文档后,在此文中将做详细的分析讨论,以及指出可能的攻击方法,供其他相关研究人员参考。
WPA3简介
本节中我们简单介绍一下WPA3相关的基本知识,在WPA2的基础上讨论在WPA3协议中做了哪些关键改进以及改进后在安全方面会有哪些提升。
根据Wi-Fi联盟官方发布的文档,WPA3仍然分为WPA3个人级和WPA3企业级两种标准,其中,WPA3企业级认证与WPA2相比差别不大,仅仅将密钥长度增加到了192位(WPA2使用的是128位的加密密钥)仍然采用EAP-SSL,EAP-SIM/EAP-AKA之类的基于认证服务器的认证方法。
那么此次协议改进最大的地方在哪里呢?没错,改动最大的地方就是WPA3个人级相对于WPA2个人级的改进,根据官方的说法,WPA3个人级有如下几个提升:
1.更强的基于密码的认证安全(官方声称即使用户使用弱密码,仍然可以得到良好的保护。)
2.使用等量同步认证——一种更安全的设备间密钥交换协议,即蜻蜓协议,可以防止通通信流量被窃听,即使被攻击者获取了握手过程,也无法解密流量。
3.密钥长度扩展到192位。
其中官方宣称的第1点建立的基础就是因为引入了蜻蜓秘钥交换协议,该协议作者在该协议的说明中声称可以避免离线字典攻击,这一点应该就是以上第1所述的可保护弱密码的原理。至于3,其实128位的对称密钥已经足够,此处提升仅仅有理论上的安全提升。看来WPA3上最明显的改进就是替换了密钥交换算法,在接下来的章节中我们就着重分析一下这个蜻蜓算法。
WPA2-PSK回顾
在开始分析蜻蜓算法之前,为了更有效的对比WPA2和WPA3密钥交换算法的差异,这里先简单介绍一下WPA2协议中设备入网认证的过程,见下图。
事实上一次完整的WPA2入网过程中,在上图所述的密钥交换过程之前还需要3次交互,分别是客户端发送Probe Request,服务器回应Probe Response,客户端发送Authentication Request服务器回应Authentication Response,接着客户端发送Association Request,服务器回应Association Response,接着开始上图所示密钥交换过程。密钥交换过程分为如下几步:
1.AP发送一个随机数AP Nonce给STA,STA通过AP的ESSID,以及自己的MAC地址,AP的MAC地址,PSK,AP发送的随机数以及自己生成的STA Nonce,这6个参数生成PMK和PTK。
2.STA发送第1步生成的随机数STA Nonce给AP,并使用上一步生成的PTK生成该数据包的消息校验值MIC附在数据包后面发送给AP,AP通过包括STA Nonce在内的同样6个参数生成自己的PMK和PTK,并用PTK校验STA发送的数据包的MIC值是否匹配,如果匹配则说明PSK正确认证通过。
3.AP将组密钥(即GTK用于加密广播以及组播包的密钥)用PMK加密并附上MIC发送给STA。
4.STA校验MIC后装入GTK并回复ACK,密钥交换结束开始加密通信。
如果你觉得以上写的太纠结,为了照顾大家特此附上代码:
#!/usr/bin/env python
import hmac
from hashlib import pbkdf2_hmac,sha1,md5
def PRF(key,A,B):
nByte = 48
i = 0
R = ''
while ( i 8 + 159)/160)):
hmacsha1 = hmac.new(key,A+"\x00" + B + chr(i),sha1)
R += hmacsha1.digest()
i += 1
return R[0:nByte]
def MakeAB(aNonce,sNonce,apMac,cliMac):
A = "Pairwise key expansion"
B = min(apMac,cliMac) + max(apMac,cliMac) + min(aNonce, sNonce) + max(aNonce, sNonce)
return (A,B)
def MakeMIC(pwd,ssid,A,B,data,wpa = False):
pmk = pbkdf2_hmac('sha1',pwd,ssid,4096,32)
ptk = PRF(pmk,A,B)
hmacFunc = md5 if wpa else sha1
mics = [hmac.new(ptk[0:16],i,hmacFunc).digest() for i in data]
return (mics,ptk,pmk)
def calcKey(essid,psk,apMac,cliMac,data0,data1,data2,data3):
ssid = essid
#print ssid
aNonce = data0[17:17+32]
#print aNonce.encode('hex')
sNonce = data1[17:17+32]
#print sNonce.encode('hex')
apMac = apMac.replace(':','').decode("hex")
cliMac = cliMac.replace(':','').decode("hex")
在2018年1月8日美国拉斯维加斯的国际消费电子展(CES)上,Wi-Fi联盟发布了最新的WPA3加密协议,作为WPA2技术的的后续版本,并在2018年6月26日,WiFi联盟宣布WPA3协议已最终完成。与WPA3相关的最核心的文档为RFC7664,其中描述的是WPA3中最大的改进,就是将原来的四次握手协议换成了新的“蜻蜓秘钥交换协议”(Dragonfly Key Exchange),该协议将认证和秘钥交换两个功能合成于一个协议。号称可以解决WPA2中未解决的几个安全问题:
1.离线密码破解——获得WPA2的四次握手包即可进行离线字典攻击,破解无线密码。
2.转发安全(Forward Secracy)——已知4次握手和无线密码的情况下,可以解密目标的所有通信流量。
3.KRACK等其他已知攻击方法。
由于WPA3还尚未普及,想来目前无论公众还是相关研究人员对WPA3的协议的实施细节所知应该并不多,所以笔者在仔细阅读RFC7664文档后,在此文中将做详细的分析讨论,以及指出可能的攻击方法,供其他相关研究人员参考。
WPA3简介
本节中我们简单介绍一下WPA3相关的基本知识,在WPA2的基础上讨论在WPA3协议中做了哪些关键改进以及改进后在安全方面会有哪些提升。 www.wnhack.com
根据Wi-Fi联盟官方发布的文档,WPA3仍然分为WPA3个人级和WPA3企业级两种标准,其中,WPA3企业级认证与WPA2相比差别不大,仅仅将密钥长度增加到了192位(WPA2使用的是128位的加密密钥)仍然采用EAP-SSL,EAP-SIM/EAP-AKA之类的基于认证服务器的认证方法。
那么此次协议改进最大的地方在哪里呢?没错,改动最大的地方就是WPA3个人级相对于WPA2个人级的改进,根据官方的说法,WPA3个人级有如下几个提升:
1.更强的基于密码的认证安全(官方声称即使用户使用弱密码,仍然可以得到良好的保护。)
2.使用等量同步认证——一种更安全的设备间密钥交换协议,即蜻蜓协议,可以防止通通信流量被窃听,即使被攻击者获取了握手过程,也无法解密流量。
3.密钥长度扩展到192位。
其中官方宣称的第1点建立的基础就是因为引入了蜻蜓秘钥交换协议,该协议作者在该协议的说明中声称可以避免离线字典攻击,这一点应该就是以上第1所述的可保护弱密码的原理。至于3,其实128位的对称密钥已经足够,此处提升仅仅有理论上的安全提升。看来WPA3上最明显的改进就是替换了密钥交换算法,在接下来的章节中我们就着重分析一下这个蜻蜓算法。 本文来自无奈人生安全网
WPA2-PSK回顾
在开始分析蜻蜓算法之前,为了更有效的对比WPA2和WPA3密钥交换算法的差异,这里先简单介绍一下WPA2协议中设备入网认证的过程,见下图。
事实上一次完整的WPA2入网过程中,在上图所述的密钥交换过程之前还需要3次交互,分别是客户端发送Probe Request,服务器回应Probe Response,客户端发送Authentication Request服务器回应Authentication Response,接着客户端发送Association Request,服务器回应Association Response,接着开始上图所示密钥交换过程。密钥交换过程分为如下几步:
1.AP发送一个随机数AP Nonce给STA,STA通过AP的ESSID,以及自己的MAC地址,AP的MAC地址,PSK,AP发送的随机数以及自己生成的STA Nonce,这6个参数生成PMK和PTK。
2.STA发送第1步生成的随机数STA Nonce给AP,并使用上一步生成的PTK生成该数据包的消息校验值MIC附在数据包后面发送给AP,AP通过包括STA Nonce在内的同样6个参数生成自己的PMK和PTK,并用PTK校验STA发送的数据包的MIC值是否匹配,如果匹配则说明PSK正确认证通过。
3.AP将组密钥(即GTK用于加密广播以及组播包的密钥)用PMK加密并附上MIC发送给STA。
4.STA校验MIC后装入GTK并回复ACK,密钥交换结束开始加密通信。
如果你觉得以上写的太纠结,为了照顾大家特此附上代码:
#!/usr/bin/env python
import hmac
from hashlib import pbkdf2_hmac,sha1,md5
def PRF(key,A,B):
nByte = 48
i = 0
R = ''
while ( i 8 + 159)/160)):
hmacsha1 = hmac.new(key,A+"\x00" + B + chr(i),sha1)
R += hmacsha1.digest()
i += 1
return R[0:nByte]
def MakeAB(aNonce,sNonce,apMac,cliMac):
A = "Pairwise key expansion"
B = min(apMac,cliMac) + max(apMac,cliMac) + min(aNonce, sNonce) + max(aNonce, sNonce)
return (A,B)
def MakeMIC(pwd,ssid,A,B,data,wpa = False):
pmk = pbkdf2_hmac('sha1',pwd,ssid,4096,32)
ptk = PRF(pmk,A,B)
hmacFunc = md5 if wpa else sha1
mics = [hmac.new(ptk[0:16],i,hmacFunc).digest() for i in data]
return (mics,ptk,pmk)
def calcKey(essid,psk,apMac,cliMac,data0,data1,data2,data3):
ssid = essid
#print ssid
aNonce = data0[17:17+32]
#print aNonce.encode('hex')
sNonce = data1[17:17+32]
#print sNonce.encode('hex')
apMac = apMac.replace(':','').decode("hex")
cliMac = cliMac.replace(':','').decode("hex")
copyright 无奈人生