SSL/TLS 握手过程详解

我们知道,HTTP 协议都是明文传输内容,在早期只展示静态内容时没有问题。伴随着互联网的快速发展,人们对于网络传输安全性的要求也越来越高,HTTPS 协议因此出现。如上图所示,在 HTTPS 加密中真正起作用的其实是 SSL/TLS 协议。SSL/TLS 协议作用在 HTTP 协议之下,对于上层应用来说,原来的发送接收数据流程不变,这就很好地兼容了老的 HTTP 协议,这也是软件开发中分层实现的体现。

SSL/TLS 握手是为了安全地协商出一份对称加密的秘钥,这个过程很有意思,下面我们一起来了解一下。

以下内容需要你对加解密、数字签名和数字证书的概念有一定了解,这里有一篇文章可以帮你快速了解这几个概念。

SSL/TLS 握手过程

上图大致描述了 SSL/TLS 的握手过程,但缺少了一些信息不利于理解,我会在后面的讲解里再列出来。

Client Hello

握手第一步是客户端向服务端发送 Client Hello 消息,这个消息里包含了一个客户端生成的随机数 Random1、客户端支持的加密套件(Support Ciphers)和 SSL Version 等信息。通过 Wireshark 抓包,我们可以看到如下信息:

Wireshark 抓包的用法可以参考这篇文章

Server Hello

第二步是服务端向客户端发送 Server Hello 消息,这个消息会从 Client Hello 传过来的 Support Ciphers 里确定一份加密套件,这个套件决定了后续加密和生成摘要时具体使用哪些算法,另外还会生成一份随机数 Random2。注意,至此客户端和服务端都拥有了两个随机数(Random1+ Random2),这两个随机数会在后续生成对称秘钥时用到。

Certificate

这一步是服务端将自己的证书下发给客户端,让客户端验证自己的身份,客户端验证通过后取出证书中的公钥。

Server Key Exchange

如果是DH算法,这里发送服务器使用的DH参数。RSA算法不需要这一步。

Certificate Request

Certificate Request 是服务端要求客户端上报证书,这一步是可选的,对于安全性要求高的场景会用到。

Server Hello Done

Server Hello Done 通知客户端 Server Hello 过程结束。

Certificate Verify

客户端收到服务端传来的证书后,先从 CA 验证该证书的合法性,验证通过后取出证书中的服务端公钥,再生成一个随机数 Random3,再用服务端公钥非对称加密 Random3 生成 PreMaster Key

Client Key Exchange

上面客户端根据服务器传来的公钥生成了 PreMaster Key,Client Key Exchange 就是将这个 key 传给服务端,服务端再用自己的私钥解出这个 PreMaster Key 得到客户端生成的 Random3。至此,客户端和服务端都拥有 Random1 + Random2 + Random3,两边再根据同样的算法就可以生成一份秘钥,握手结束后的应用层数据都是使用这个秘钥进行对称加密。为什么要使用三个随机数呢?这是因为 SSL/TLS 握手过程的数据都是明文传输的,并且多个随机数种子来生成秘钥不容易被暴力破解出来。客户端将 PreMaster Key 传给服务端的过程如下图所示:

Change Cipher Spec(Client)

这一步是客户端通知服务端后面再发送的消息都会使用前面协商出来的秘钥加密了,是一条事件消息。

Encrypted Handshake Message(Client)

这一步对应的是 Client Finish 消息,客户端将前面的握手消息生成摘要再用协商好的秘钥加密,这是客户端发出的第一条加密消息。服务端接收后会用秘钥解密,能解出来说明前面协商出来的秘钥是一致的。

Change Cipher Spec(Server)

这一步是服务端通知客户端后面再发送的消息都会使用加密,也是一条事件消息。

Encrypted Handshake Message(Server)

这一步对应的是 Server Finish 消息,服务端也会将握手过程的消息生成摘要再用秘钥加密,这是服务端发出的第一条加密消息。客户端接收后会用秘钥解密,能解出来说明协商的秘钥是一致的。

Application Data

到这里,双方已安全地协商出了同一份秘钥,所有的应用层数据都会用这个秘钥加密后再通过 TCP 进行可靠传输。

双向验证

前面提到 Certificate Request 是可选的,下面这张图展示了双向验证的过程:

握手过程优化

如果每次重连都要重新握手还是比较耗时的,所以可以对握手过程进行优化。从下图里我们看到 Client Hello 消息里还附带了上一次的 Session ID,服务端接收到这个 Session ID 后如果能复用就不再进行后续的握手过程。

除了上述的 Session 复用,SSL/TLS 握手还有一些优化技术,例如 False Start、Session Ticket 等,这方面的介绍具体可以参考这篇文章

总结

前面我们一起详细地了解了整个 SSL/TLS 的握手过程,这部分知识在平时的开发过程中很少用到,但能让我们更清楚地了解 HTTPS 的工作原理,而不仅仅是只知道 HTTPS 会加密数据十分安全。同时这个过程也是各种加密技术的一个经典运用,也能帮助我们加深加密相关技术的理解。最后,建议大家也用 Wireshark 实际抓包体验一下这个过程来加深印象,enjoy~

参考资料

www.ruanyifeng.com/blog/2014/0…

segmentfault.com/a/119000000…

imququ.com/post/optimi…

blog.youkuaiyun.com/fw0124/arti…


最后做个推广,欢迎关注公众号 MrPeakTech,我从这里学到很多,推荐给大家,共同进步~

### SSL/TLS 握手过程详解 SSL/TLS 协议的核心在于其握手阶段,该阶段负责协商加密算法、交换密钥以及验证身份,从而建立安全的通信通道。以下是详细的握手过程描述: #### 1. **初始连接** 当客户端尝试访问支持 HTTPS 的服务时,它会向服务器发送一个 `ClientHello` 消息。此消息包含了客户端支持的最高 TLS 版本、可用的密码套件列表以及其他必要的参数[^1]。 #### 2. **服务器响应** 服务器接收到 `ClientHello` 后,返回一个 `ServerHello` 消息。此消息确认了双方使用的 TLS 版本和选定的密码套件,并附带服务器证书用于身份验证[^1]。 #### 3. **公钥交换与身份验证** 如果使用的是基于 RSA 的密钥交换机制,则客户端利用服务器证书中的公钥对预主密钥(Pre-Master Secret)进行加密并发送给服务器;如果是基于 Diffie-Hellman 的方案,则在此阶段完成临时 DH 参数的交换[^5]。随后,客户端会对服务器证书进行校验以确保其合法性[^2]。 #### 4. **生成共享秘密** 一旦完成了上述步骤,双方都将独立计算出会话所需的主密钥(Master Secret),并通过一系列派生操作得到最终的对称加密密钥[^1]。 #### 5. **应用层数据传输准备** 在成功构建起共同的秘密之后,客户端和服务端分别通知对方已准备好切换至加密模式下继续通讯(`ChangeCipherSpec`),紧接着再各自发出一条带有新商定好的加密方式保护的消息(通常是Finished message),用来证明之前的流程无误并且现在可以正式开始传送实际负载的数据流了[^4]。 --- 对于可能遇到的一些常见问题及其解决方案如下所示: - 如果发现无法正常完成握手,可以通过命令行工具OpenSSL来进行调试:`openssl s_client -connect example.com:443 -tlsextdebug -state`,这可以帮助定位具体在哪一步出现了错误[^3]. - 使用在线资源如SSLLabs提供的免费扫描功能也可以快速评估目标站点是否存在配置不当等问题:ssllabs.com/ssltest. ```bash # 示例:通过 OpenSSL 测试特定网站的 TLS 配置 openssl s_client -connect www.example.com:443 -tls1_2 -cipher "AES256-SHA" ``` 另外推荐开发者们亲自实践捕获真实环境下的网络流量来学习整个交互细节,比如借助Wireshark软件观察每一个分组的具体内容结构等等[^4]. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值