本文的初衷是:随着数字信息时代的到来(DT), 生活中的方方面面几乎可以完全数字信息化,例如个人性别、地址、联系方式、财产、生活习惯、饮食习惯、工作情况、学历信息、健康状况、兴趣爱好等等都存储到互联网上,数据安全越来越重要,国家、公司、个人越来越重视信息安全。而SSL/TLS相比于其他的安全协议,如IPSec等协议,存在诸多优势,应用场景更加广泛,更加常用。此外还有一个非常重要的原因:因为常用、重要,各个公司都在使用,导致SSL/TLS是面试中的一个重难点,也是重灾区。
综合以上原因,因此准备详细整理下SSL/TLS相关知识,并由浅入深,逐步从原理深入到实现。文章计划包括如下内容:
- SSL/TLS的发展历程
- SSL/TLS的协议原理
- 常见的SSL/TLS实现方式, 如openssl、golang中的实现原理
- TLS卸载
- SSL VPN
- …
说句实话,如果能把上述内容整理完毕,我估计能写成书…估计又要出一个专栏了,前一个IPsec专栏的坑还没有填呢!
谋事在人,成事在天,尽力而为吧。
SSL/TLS专栏导航页
文章目录
1. 基于ECDHE的TLS握手流程概
上图便是一个基于HTTPS通讯的完整过程,涉及:
- TCP三次握手
- TLS握手
- 加密数据传输
- TCP四次挥手
下面开始介绍基于ECDHE的TLS的握手流程。
客户端首先发送一个【ClientHello】消息作为TLS握手的开始。该消息中主要包含:TLS的版本号, 客户端随机数(Client Random), 密钥套件列表以及SessionID信息。
如果报文中的SessionID不为空,则说明客户端想复用此session的密码信息。服务端如果同意则在ServerHello中使用相同的SessionID, 如果不同意则重新生成一个新的SessionID。
这里说一下:密码套件的格式。
TLS的密钥套件不同于IPSec密钥套件。
- IPSec密钥套件中加密算法、哈希算法、认证算法可以互相自由组合,协商的是每一种算法,最后组合成一个密码套件。
- 而TLS则直接协商密码套件,每一种密码套件中密码算法组合是固定的。
3. 第二次握手TLS密码套件组
TLS——密钥交换算法——签名算法——WITH——加密算法——摘要算法
其中密钥交换算法和签名算法可以合二为一。
TLS第二次握手报文包含的内容比较多。有时候一个报文包含所有载荷,有时各个载荷单独发送。如果看到单独发送的载荷,莫要奇怪。
第二次握手主要包含了四个载荷:
- Server Hello
- Certificate
- Server Key Exchange
- Server Hello Done
下面分别介绍这四个载荷:
3.1 Server Hello载荷
Server Hello中的内容与Client Hello中基本一致。包括:TLS版本号, 服务器端的随机数(Server Random), 服务器端想要使用的SessionID,服务器端选择的加密套件。
如果此SessionID与ClientHello中的SessionID相同,则说明服务器同意复用此session; 如果不同则说明需要进行重新协商。我这次抓的报文两者sessionID并不相同,因此需要完整的TLS协商流程。
服务端选择的算法套件是:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030), 它的意思是:
- 密钥交换算法采用:ECDHE
- 签名算法采用:RSA
- 加密算法采用:AES对称算法,密钥长度为256bit, 模式为:GCM。
- 摘要算法采用:SHA284
3.2 Server Key Exchange载荷
由于采用的是ECDHE进行密钥交换,因此服务端需要将采用的椭圆曲线信息,公共值信息发送给客户端。此外为了防止信息被篡改,服务端使用RSA算法对DH公钥做一个签名。这个Pubkey???
3.3 Server Hello Done载荷
最后发送一个ServerHelloDone消息,表明:“这就是Server Hello阶段发送的所有信息,你可以忙活了”。它的报文内容很简单,啥也没有。
握手阶段交互完毕,通过Hello阶段握手,客户端和服务端交换的信息如下:Client Random, Server Random, 使用的椭圆曲线,椭圆曲线公钥。
客户端收到服务端的ServerHello阶段信息后,首先会对服务端的证书进行验证,验证服务端证书可能涉及认证链的问题。如果验证通过,说明当前服务器身份没有问题。如果验证不通过,则会提示相应的错误信息(好像是Bad certificate)。对服务端的身份认证一般情况下是可以设置的,客户端可以选择验证也可以不验证。
服务端验证完毕后,客户端会生成一个随机数,作为ECDHE的临时私钥,并通过服务端在ServerKeyExchange中发送的椭圆曲线参数,计算出自己的ECDHE公钥信息。然后通过ClientKeyExchange发送给服务端。
之后,客户端会根据手里中的信息:Client Random, Server Random, ECDHE协商出的共享密钥,计算出会话密钥(主密钥)。 其他密钥都是在此基础上依次获取的。密钥计算完毕后,发送ChangeCipherSpec消息,通知服务端后续报文采用新协商的安全参数进行安全通讯。
最后发送一个Encrypted Handshake Message消息,把之前所有的握手报文做一个摘要,然后使用协商的对称密钥进行加密发送给服务端。依次来验证双方本次握手协商的安全参数是否可用。
第四次握手与第三次握手非常相似。服务器端收到ClientKeyExchange后,获取到里面的客户端DH算法公钥,计算出ECDHE协商出的共享密钥。 然后在利用手中的Client Random, Server Random, ECDHE协商出的共享密钥计算出会话密钥。最后根据会话密钥依次生成其他密钥。
在此过程中服务端同样会发送ChangeCipherSpec,通知客户端,麻溜采用新协商的安全参数进行通讯,以后发给你的数据全部进行加密。此外服务端同样对所有的握手报文做一个摘要,并进行加密然后给客户端发送一个Encrypted Handshake Message消息,验证客户端是否可以正常解密。
至此, 基于ECDHE的TLS协商完毕。之后双方使用协商出的安全参数进行加密通讯。加密的应用层协议使用TLS Record Layer Protocal进行封装。
CSDN提供的MD模板是真的难看,又不能直接导入HTML格式的网页,此外对于github图床上的支持很不友好,挨个找图片真是个体力活!!! 我自己的主题还是蛮漂亮的,可惜了????????????