</h1>
<div class="clear"></div>
<div class="postBody">
一、DTLS
DTLS 是指 Datagram Transport Level Security,即数据报安全传输协议;
其提供了UDP 传输场景下的安全解决方案,能防止消息被窃听、篡改、身份冒充等问题。
DTLS作为UDP版本的TLS,具备了同样的安全机制和防护等级,在版本上存在对应关系,如DTLS 1.2版本对应于 TLS1.2。
二、握手流程
前面的文章介绍过TLS的相关算法流程,对于传输层安全来说,密钥交换机制和数据加密及签名算法决定了整个方案的安全等级。
而密钥协商都必须通过握手流程完成,因而这是理解DTLS的关键要点。
根据RFC6347定义,一个DTLS握手流程如下所示:
------ ------
ClientHello --------> Flight 1
<------- HelloVerifyRequest Flight <span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">
ClientHello --------> Flight 3
ServerHello \
Certificate</span>*<span style="color: rgba(0, 0, 0, 1)"> \
ServerKeyExchange</span>* Flight <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">
CertificateRequest</span>* /
<-------- ServerHelloDone /<span style="color: rgba(0, 0, 0, 1)">
Certificate
ClientKeyExchange
CertificateVerify Flight 5
[ChangeCipherSpec] /
Finished --------> /
[ChangeCipherSpec] \ Flight </span><span style="color: rgba(128, 0, 128, 1)">6</span>
<-------- Finished /</pre>
三、关键算法
DTLS 由于网络IO机制的限制,其支持的算法为TLS的子集。
这里将DTLS算法描述为一种算法可能并不恰当,因为一个完整的DTLS过程中,所涉及的算法是很多的,比如
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,这其中涉及的算法包括:
1 密钥交换算法 ECDHE_RSA,这是由ECC和DH密钥交换算法衍生出来的算法;
2 动态密钥算法 AES_128_GCM,用于实现数据包的加解密;
3 MAC算法 HMAC_SHA256,用于创建加密数据块的摘要;
4 伪随机函数 PRF,TLS1.2 定义其与MAC算法一致。
因此将一个DTLS过程中协商使用的算法列表称谓算法套件,即CipherSuite,个人认为这个定义还是比较好理解的。
以下是几个常用的 CipherSuite
TLS_PSK_WITH_AES_128_CBC_SHA256 TLS_PSK_WITH_AES_128_CCM_8 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
算法的选择
不同算法带来的数据传输及计算性能开销是不同的,尤其在UDP场景下,我们可能更关注的是网络IO的不稳定性,MTU过载导致丢包等等问题。
非对称密钥加解密的性能是低下的,尤其在微型设备上,其计算资源十分有限,因此采用轻量级的密钥交换算法可能是最佳方案。
PSK(Pre shared key) 算法中,服务端为终端预置了密钥,在交换过程中凭一个identity信息可快速完成信息交换,这个极大简化了密钥交换的工作。
一个典型的PSK握手流程如下所示:
Client Server ------ ------ ClientHello --------><--------<span style="color: rgba(0, 0, 0, 1)"> HelloVerifyRequest (contains cookie) ClientHello </span>--------><span style="color: rgba(0, 0, 0, 1)"> (with cookie) ServerHello </span>*<span style="color: rgba(0, 0, 0, 1)">ServerKeyExchange </span><--------<span style="color: rgba(0, 0, 0, 1)"> ServerHelloDone ClientKeyExchange ChangeCipherSpec Finished </span>--------><span style="color: rgba(0, 0, 0, 1)"> ChangeCipherSpec </span><--------<span style="color: rgba(0, 0, 0, 1)"> Finished Application Data </span><-------> Application Data</pre>
PSK方案的缺陷在于其无法较好的防止PSF(Perfect Forward Secrecy)攻击问题,一旦PSK泄露,将丢失安全性。
然而方案的选择并非力求完美,我们往往要找的是最适合需求的方案。PSK方案轻量级,节省开销,且具备一定的通用性;
而对于安全级别特别高的场景,你或许可以选择ECDHE交换算法,而为了节省证书传输的开销,你可以采取一些扩展机制,如Raw Public Key。
这是一种允许直接将公钥数据替代证书的方案,可一定程度节省CA证书传输及信任链校验的开销。
RFC7925 对物联网场景下的DTLS提供了一些扩展定义,可供参考。
四、防护机制
A. 握手流程
握手流程必须严格按顺序执行,因此有必要保证消息可靠到达,按序接收。
重传
DTLS 采用了简单的重传机制来确保握手消息到达,流程如下:
Client Server ------ ------ ClientHello ------>X</span><--<span style="color: rgba(0, 0, 0, 1)"> HelloVerifyRequest (lost) [Timer Expires] ClientHello </span>------><span style="color: rgba(0, 0, 0, 1)"> (retransmit)</span></pre>
顺序
为保证握手消息按序传输,每个handshake消息包含了一个序列号;
接收方直接处理属于当前步骤的消息,对于提前到达的消息则提供一个队列进行缓存;
分段
理论上一个握手消息可能接近2^24-1字节, 而UDP 传输中往往限制于MTU 大小,一般为1500字节;
因此 DTLS 要求针对握手消息实现分段,每一个握手消息都可能包含了fragment的offset 和长度,由接收端重新组装;
重复
DTLS 定义了消息重放检测机制,由接收方维护一个bitmap用于记录一接收的数据包,用于检测重复数据包;建议解决方案实现对bitmap的自动老化。
该做法借鉴了IPsec AH/ESP机制。
B. 数据包传输
加解密算法很可能依赖于上下文,如CBC组合算法中,当前数据包的解密依赖于上一个数据包,因此有必要保证数据包传输的可靠和有序;
DTLS为每个加密数据包增加了MAC鉴权摘要,用于保证数据包的完整性;此外显式附带了一个SN号用于排序。
C. Dos攻击
攻击者很可能会利用一些已入侵的主机对服务器展开攻击(数据包转发),通过瞬时对DTLS服务器发送大量的握手消息导致服务器资源耗尽;
DTLS定义了基于cookie验证的机制来预防攻击,如前面流程中涉及的HelloVerifyRequest便是用于进行cookie验证
Client Server ------ ------ ClientHello ------><-----<span style="color: rgba(0, 0, 0, 1)"> HelloVerifyRequest (contains cookie) ClientHello </span>------><span style="color: rgba(0, 0, 0, 1)"> (with cookie) [Rest of handshake]</span></pre>
Cookie的算法:HMAC(Secret, Client-IP, Client-Parameters)
其中Secret由server端内置,用于计算cookie值,client端需要在接收到VerifyRequest后提供同样的cookie值;
server端根据发送方IP计算cookie值,一旦返现不一致则判定为非法数据。
D. 会话恢复
握手流程所占的开销是较大的,与TLS类似,DTLS也定义了会话恢复机制。
Client Server ------ ------
ClientHello --------> Flight 1
ServerHello \
[ChangeCipherSpec] Flight </span><span style="color: rgba(128, 0, 128, 1)">2</span>
<-------- Finished /<span style="color: rgba(0, 0, 0, 1)">
[ChangeCipherSpec] \Flight 3
Finished -------->
简单原理
握手成功之后,Server端将生成SessionID 返回,客户端在下次连接时附带SessionID;
若验证通过,可直接沿用原有的会话数据,包括协商算法和密钥。
五、与TLS的不同
最后,总结下与TLS的差异吧
-
TLS 建立于TCP可靠的传输机制之上,而DTLS基于UDP,必须自建保障机制:
DTLS 必须检测MTU大小,当应用层数据包超过时报错;
为防止握手的IP数据包超载导致丢失,DTLS 针对握手消息实现fragment处理。
-
TLS 在传输出错时会中断连接,而DTLS需兼容多种出错场景,出错时往往直接丢弃处理;
- DTLS不支持RC4流加密算法。
六、参考文档
DTLS1.2 定义
https://tools.ietf.org/html/rfc6347
DTLS -IOT extension
https://tools.ietf.org/html/rfc7925#section-4.1
TLS /SSL 原理解析
http://seanlook.com/2015/01/07/tls-ssl/
关于TLS的隐式向量
https://en.wikipedia.org/wiki/Initialization_vector
老外写的关于PSF的文章
https://vincent.bernat.im/en/blog/2011-ssl-perfect-forward-secrecy.html<div style="float: left; padding-right: 15px"> <img src="https://images.cnblogs.com/cnblogs_com/littleatp/1241412/o_qrcode_for_gh_b2cf486409a0_258.jpg" style="width: 120px; height: 120px"> </div> <div style="padding-top: 15px"> <p> 作者: <a href="http://www.cnblogs.com/littleatp/">美码师(zale)</a> </p> <p> 出处: <a href="http://www.cnblogs.com/littleatp/">http://www.cnblogs.com/littleatp/</a>, 如果喜欢我的文章,请<b style="font-size: medium">关注我的公众号</b> </p> <p> 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 <a href="#" style="color: #0; font-size: medium">原文链接</a> 如有问题, 可留言咨询. </p> </div> <div style="clear: both"></div>
20<div class="clear"></div> <div id="post_next_prev"> <a href="https://www.cnblogs.com/littleatp/p/6354441.html" class="p_n_p_prefix">« </a> 上一篇: <a href="https://www.cnblogs.com/littleatp/p/6354441.html" title="发布于 2017-01-28 19:49">实现jul 日志重定向到 slf4j</a> <br> <a href="https://www.cnblogs.com/littleatp/p/6358593.html" class="p_n_p_prefix">» </a> 下一篇: <a href="https://www.cnblogs.com/littleatp/p/6358593.html" title="发布于 2017-01-31 01:23">DTLS-PSK算法抓包解析</a>
</div>