DTLS协议(基于UDP)中clientserver的认证过程和密钥协商过
我的总结:DTLS的握⼿就是协商出⼀个对称加密的秘钥(每个客户端的秘钥都会不⼀样),之后的通信就要这个秘钥进⾏加密通信。协商的过程要么使⽤⾮对称加密算法进⾏签名校验⾝份,要么通过客户端和服务器各⾃存对⽅信息进⾏对⽐校验⾝份。
1.DTLS介绍
1.1 DTLS的作⽤
互联⽹先驱们最开始在设计互联⽹协议时主要考虑的是可⽤性,安全性是没有考虑在其中的,所以传输层的TCP、UDP协议本⾝都不具备安全性。SSL/TLS协议是基于TCP socket,利⽤加密、基于数字证书的⾝份验证等机制在传输层和应⽤层之间构建了⼀个端到端的安全通道,保证了传输数据的加密性。
但是SSL/TLS协议并不能⽤于UDP协议,⽽UDP也有安全传输的需求,于是产⽣了DTLS协议(Datagram TLS)。
即DTLS的作⽤为给UDP提供端到端的安全通道,就像SSL/TLS对TCP的作⽤⼀样。并且DTLS尽可能参考了SSL/TLS协议的安全机制,在具体实现上复⽤了70%的TLS代码。
1.2 DTLS的特点
UDP协议是不⾯向连接的不可靠协议,且没有对传输的报⽂段进⾏加密,不能保证通信双⽅的⾝份认证、消息传输过程中的按序接收、不丢失和加密传送。
⽽DTLS协议在UDP提供的socket之上实现了客户机与服务器双⽅的握⼿连接,并且在握⼿过程中通过使⽤PSK或ECC实现了加密,并且利⽤cookie验证机制和证书实现了通信双⽅的⾝份认证,并且⽤在报⽂段头部加上序号,缓存乱序到达的报⽂段和重传机制实现了可靠传送。在握⼿完成后,通信双⽅就可以利⽤握⼿阶段协商好的会话密钥来对应⽤数据进⾏加解密。
1.3 DTLS协议层次
DLTS协议分为两层,下层为记录层(record层),record包的内容分为头部和载荷两部分。record包的载荷即为上层的内容。DTLS上层的包的类型分为三种,分别是握⼿消息,警告消息,应⽤数据;如图⼀所⽰。
图⼀.DTLS协议的层次
在整个DTLS协议的通信过程中,通信双⽅构造报⽂段的过程都是先产⽣上层的载荷消息(如握⼿消息,
应⽤数据,警告消息),然后添加头部,构成完整的上层消息。接着再以此作为记录层的载荷,最后添加记录层的头部,构成完整的记录报⽂段,最后调⽤UDP的socket接⼝,发送给另⼀⽅。
加密过程是只对记录层的载荷(即上层消息,此协议中被加密的消息是finished消息和应⽤数据两种)进⾏加密,所以接收⽅在收到记录消息后,⾸先要做的也是判断记录消息是否被发送⽅加密,若是,则应先解密才能读取出明⽂数据以进⾏后⾯的处理。
2.client/server建⽴DTLS连接的握⼿过程
2.1 整个握⼿阶段的交互过程
DTLS的传输阶段分为两个:握⼿阶段和握⼿建⽴之后的传输应⽤数据阶段。
DTLS的握⼿阶段如下图⼆所⽰:
图⼆.DTLS协议客户机与服务器握⼿阶段的交互过程
客户机向服务器发起连接,服务器可以根据配置选择是否验证客户机的cookie和证书(即是否向客户机发送client_hello_verify和certificate_request报⽂段)。
2.2 DTLS的cookie验证机制
由于DTLS是基于UDP的,所以可能会遭受两种形式的拒绝服务攻击。⼀种是类似于对TCP的资源消耗攻击,另⼀种是放⼤攻击,即恶意攻击者仿造被攻击者的IP地址发通信初始化报⽂段给服务器,⽽服务器会返回⼀个体积⼤很多的证书给被攻击者,超⼤量证书有可能造成被攻击者的瘫痪。
cookie机制要求客户机重复发送服务器之前发送的cookie值来验证通信⽅的源IP地址确实可以通信,由此可以减少拒绝服务攻击的危害。
cookie验证⾝份的具体机制为:
协议规定客户机发送的第⼀个报⽂段client_hello中含有cookie的值这⼀项(有可能为空)。服务器检验收到的该报⽂段中的cookie值,如果cookie为空,则说明之前没建⽴过连接,服务器根据客户机的源IP地址通过哈希⽅法随机⽣成⼀个cookie,并填⼊client_hello_verify中发送给客户机。
客户机再在第⼆次发送的client_hello报⽂段中填⼊服务器之前发过来的cookie,服务器第⼆次收到该报⽂段之后便检验报⽂段⾥⾯的cookie 值和服务器之前发给该主机的cookie值是否完全相同,若是,则通过cookie验证,继续进⾏握⼿连接;若不是,则拒绝建⽴连接。
2.3 client_hello报⽂段和server_hello报⽂段的内容socket通信报文格式
client_hello报⽂段的内容除cookie外,还有客户机产⽣的32字节的随机数,其中前4字节为时间戳,后28字节为系统产⽣的随机数。此外,该报⽂段的内容还有客户机⽀持的加密⽅式(PSK或者ECC)和压缩⽅式,供服务器进⾏选择。
在通过cookie校验后,服务器发送server_hello报⽂段给客户机。该报⽂段包含有服务器产⽣的32字节的随机数,和服务器选中的⽤来进⾏之后的会话的加密⽅式和压缩⽅式。
2.4 certificate报⽂段的内容
在服务器发给客户机的证书报⽂段中,包含有服务器证书的公钥;客户机接收到该报⽂段后,按照协议规定,从报⽂段的对应位置中读取出服务器证书的公钥存⼊相关变量中。客户机通过这个公钥验证接下来服务器的报⽂server_key_exchange是否有效。
2.5 基于ECC加密⽅式的ECDH秘钥交换协议和ECDSA数字签名算法
若协议所选加密⽅式为ECC(椭圆曲线加密),则在server_key_exchange报⽂段的构造过程中会使⽤ECDH(椭圆曲线秘钥交换协议)和ECDSA(椭圆曲线数字签名算法)。ECDH和ECDSA分别是ECC和DH(diffie-hellman)秘钥交换协议、DSA(数字签名算法)的结合。ECDSA:⽤于数字签名,是ECC与DSA的结合,整个签名过程与DSA类似,所不⼀样的是签名中采取的算法为ECC,最后签名出来的值也是分为r,s。ECDH:是基于ECC(Elliptic Curve Cryptosystems,椭圆曲线密码体制,参看ECC)的DH( Diffie-Hellman)密钥交换算法。
ECDH⽤途:
由于通过ECDH,双⽅可以在不共享任何秘密的前提下协商出⼀个共享秘密,因此,ECDH⼴泛⽤于协议之中,通过ECDH得到对称加密密钥。如TLS中的
*_ECDH_*密码套件。使⽤DH算法的协
议,都可以升级到ECDH算法。ECDH具有ECC的⾼强度、短密钥长度、计算速度快等优点。
密钥交换过程:
假设密钥交换双⽅为Alice、Bob,其有共享曲线参数(椭圆曲线E、阶N、基点G)。
1.Alice⽣成随机整数a,计算A=a*G。Bob⽣成随机整数b,计算B=b*G。
2.Alice将A传递给Bob。A的传递可以公开,即攻击者可以获取A。由于椭圆曲线的离散对数问题是难题,所以攻击者不可以通过A、G计算出a。Bob将B传递给Alice。同理,B的传递可以公开。
3.Bob收到Alice传递的A,计算Q=b*A
4.Alice收到Bob传递的B,计算Q‘=a*B
总结:
Alice、Bob双⽅即得Q=b*A=b*(a*G)=(b*a)*G=(a*b)*G=a*(b*G)=a*B=Q' (交换律和结合律),即双⽅得到⼀致的密钥Q。
在server_key_exchange报⽂段中,包含有所选⽤的椭圆曲线E,阶N和基点G的x,y坐标,客户机在收到这个报⽂段后,进⾏对应的格式检验,并读取数据,因此服务器和客户机共同获得约定好的⽤来进⾏ECDH秘钥协商交换协议的参数,从⽽可以共同协商出相同的对话秘钥(对称加密的秘钥)⽤于加密之后的会话内容。
同时,为了防范中间⼈攻击,服务器还在server_key_exchange报⽂段的末尾对整个报⽂段进⾏了ECDSA数字签名。具体签名过程为先⽤client_hello报⽂段和server_hello报⽂段中的2个32字节的随机数作为函数参数,利⽤sha256哈希算法对server_key_exchange报⽂段本⾝的载荷产⽣摘要,然后再⽤
服务器的私钥和sha256哈希算法进⾏ECDSA数字签名,得到签名结果r和s,并写⼊server_key_exchange报⽂段的末尾。
客户机在收到server_key_exchange报⽂段后,先进⾏各数值项格式的校验,然后提取出报⽂段末尾的签名值r和s。之后,⽤已经读取出的服务器的公钥的x,y坐标值来对server_key_exchange报⽂段进⾏ECDSA签名验证,若结果和报⽂段中的r和s值⼀致,则报⽂段通过验证。
2.6 基于PSK加密⽅式的⾝份认证过程和会话秘钥产⽣过程
整个DTLS协议的加密⽅式可选⽤ECC或PSK(预共享秘钥,PreSharedKey)两种。若为ECC,则通过ECDH协议来进⾏通信双⽅的秘钥协商;若为PSK,则直接以通信双⽅事先就已经约定好了的秘钥为基础来进⾏加密通信。
对于PSK加密通信来说,验证对⽅的通信⾝份⾮常关键。所以通信双⽅会在本地存取对⽅的psk_id(即⾝份标志)和psk_id_length(⾝份标志长度),通过⽐较收到的报⽂段中的psk_id,psk_id_length和本地存储的是否完全⼀致来进⾏对⽅⾝份的验证。
在整个通信过程中,采⽤PSK与ECC的区别主要体现在server_key_exchange报⽂段、client_key_exchange报⽂段的内容不同和双⽅计算得到预主秘钥⽅式的不同。
当采⽤PSK加密时,server_key_exchange报⽂段和client_key_exchange报⽂段的内容分别是服务器与客户机各⾃的psk_id和
psk_id_length,由此双⽅可以互相知道对⽅的psk_id和psk_id_length。
之后,双⽅都会对收到的报⽂段进⾏检验,只有psk_id和psk_id_length与本地存储的完全⼀致才会进⾏后⾯的通信。
当双⽅都通过⾝份验证后,双⽅再各⾃⽤相同的函数产⽣预主秘钥,⽽函数的参数包括之前通信阶段中双⽅各⾃产⽣的32字节的随机数,由此可以保证虽然本地存储的psk秘钥不变,但每次临时通信时的会话秘钥还是会⼀直变化的,从⽽增强了抗攻击性。
双⽅产⽣预主秘钥后,再调⽤和使⽤ECC加密的相同⽅式来产⽣主秘钥,即⽤于之后会话通信的对称秘钥,该过程中依然会⽤到双⽅产⽣的32字节的随机数。
由此,通信双⽅使⽤PSK加密⽅式来实现了⾝份认证和会话秘钥的产⽣。
2.7 server_hello_done报⽂段和client_key_exchange报⽂段的内容
服务器发送的server_hello_done报⽂段的载荷部分为空,只是发给客户机来作为标志,表⽰服务器当前阶段的报⽂段已经发送完毕。
客户机在收到server_hello_done报⽂段后,发送client_key_exchange报⽂段给服务器,⾥⾯包含了⽤于秘钥协商的基点的x,y坐标(相当于Bob的B),并且不同于server_key_exchange报⽂段,客户机并没有在报⽂段的末尾进⾏ECDSA数字签名。
2.8 客户机产⽣会话秘钥
之后,客户机再通过ecdh_pre_master_secret函数来产⽣⽤于之后会话的预主秘钥。其中函数的参数包括客户机⾃⼰的私钥,和服务器共享的⽤于ECDH秘钥协商算法的基点的x,y坐标(我觉的应该是Bob的b(是否就是所说的客户机⾃⼰的私钥)和从server_key_exchange报⽂段得到A)。
产⽣预主秘钥后,再根据之前阶段客户机和服务器分别产⽣的32字节的随机数产⽣主秘钥master_secret,此时主秘钥为对称秘钥,⽤于之后会话的加解密。
2.9 change_cipher_spec报⽂段和finished报⽂段的内容
客户机计算出会话秘钥后,发送change_cipher_spec报⽂段给服务器,这个报⽂段的有效载荷为空,⽤来作为标志通知服务器,表⽰客户机已经算出主秘钥,之后发送的报⽂段会采⽤主秘钥加密。
握⼿阶段中客户机发送的最后⼀个报⽂段为finished报⽂段,载荷内容为MAC值(消息验证码),⽤于给服务器做认证。并且值得注意的是,finished报⽂段作为记录层的载荷部分在发送时已经⽤上⼀步产⽣
的会话秘钥进⾏加密编码。
2.10 服务器产⽣会话秘钥
服务器在收到客户机发送过来的finished报⽂段后,也会和客户机⽤ECDH秘钥协商算法经过相同的流程,调⽤相同的函数先产⽣预主秘钥,再产⽣主秘钥。
2.11 握⼿阶段的结束
最后,服务器产⽣经会话秘钥加密后的finished报⽂段给客户机,标志整个握⼿阶段的结束。
客户机收到服务器发过来的finished报⽂段后,便可发送应⽤数据。并且应⽤数据会⼀直⽤会话秘钥加密,从⽽实现了UDP所不具备的安全性。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。