找回密码
 立即注册
首页 业界区 安全 TLS 详细解释

TLS 详细解释

史穹逊 2025-5-31 23:36:20
前言

什么是tls呢?
tls 全称是transpot layer security,它的前身是ssl,secure sockets layer。
现在已经不用ssl了,但是有些地方也会说是ssl,其实是tls,只是一些老的说法。
那么来看下tls的全称。
正文

首先tls 是需要证书的,这个证书的作用是用来验证,当前的交互单位是真正的服务端,而不是被别人伪造的,
那么是如何证明的呢?
那么自然是通过ca单位进行验证了。
当客户端拿到证书后,那么客户端会去验证这个证书,比如有效期,证书是否吊销等等。
通过一些列验证,证明证书是对的。
那么问题来了,客户端是如何拿到证书的呢?
  1. ClientHello       → 客户端支持的TLS版本、密码套件、随机数
  2. ServerHello      ← 服务器选择的密码套件、随机数
  3. Certificate      ← 服务器证书(含公钥)
复制代码
嗯,这样就拿到证书了。
也就是说客户端会发起clienthello,协商后面使用的tls版本、密码套件、随机数等。
这里我们就提出了一个问题,既然公钥是公开的,那么好像这一步好像都可以伪造啊。
是的,如果仅仅是这里,那么伪造服务端好像没啥问题啊,因为公钥是公开的。
但是我们的目的不是为了验证证书,而是数据加密,这里是为了客户端拿到的一定是服务端的公钥,而不是伪造的公钥,这里很重要。
好了,现在保证了客户端拿到的公钥一定是服务端的公钥了。
那么如何加密呢?
直接用公钥加密和用公钥解密? 这样不太行,因为公钥是公开的嘛。
一开始有rsa 秘钥交换,这种方式,只是用公钥加密私钥解密来交换后需的加解密方式。
这里就很危险,娓娓道来。
RSA密钥交换的握手流程

  • Client Hello
客户端向服务器发送支持的TLS版本、密码套件列表(包含TLS_RSA_WITH_*)等。

  • Server Hello
服务器选择TLS_RSA密钥交换的密码套件(如TLS_RSA_WITH_AES_256_CBC_SHA),并发送服务器证书(包含RSA公钥)。

  • Premaster Secret生成
客户端生成一个48字节的预备主密钥(Premaster Secret)。
用服务器的RSA公钥加密该密钥,发送给服务器(ClientKeyExchange消息)。

  • 密钥派生
服务器用RSA私钥解密得到Premaster Secret。
双方根据Premaster Secret、随机数(ClientHello和ServerHello中的)派生会话密钥(加密数据的对称密钥)。
这样看起来好像没啥问题哈,别人好像拿不到Premaster Secret似乎是安全的,因为公钥加密的必须用私钥来解密,然后公钥又是通过验证的。
为什么不安全?

  • 缺乏前向保密(Forward Secrecy)
若服务器的RSA私钥未来被泄露(如被破解或窃取),攻击者可解密所有历史通信(因会话密钥由RSA加密传输)。
只要是私钥后面被拿到了,前面的会话就可以拿到Premaster Secret,向前保密性是没有的。
前向保密要求每次会话的密钥独立,即使长期私钥泄露也不影响历史通信。RSA密钥交换无法满足这一点。

  • 依赖单一密钥
RSA密钥交换完全依赖服务器的RSA密钥对。相比之下,DH(Diffie-Hellman)或ECDH密钥交换通过临时密钥对实现每次会话的独立密钥协商。

  • 密钥管理风险
长期使用的RSA私钥若未妥善保护(如未使用HSM或定期轮换),风险更高
其实总得来说就是缺乏向前保密性,就是私钥被获取,历史的都是问题。
那么如何改善呢? 这个时候就需要临时性,也就是每一次会话都应该会话结束后,就解不开。
既然有临时状态,那么如何才能实现临时性呢?
现在的秘钥生成是 security key = fun(客户端随机数)
依赖客户端随机数,但是这个客户端随机数又是可以通过私钥解开的,这是个传输问题。
如果客户端随机数不仅仅通过私钥解开,之所以能够向前是因为私钥具备稳定性,而不是临时性,而是还存在一个临时的rsa呢?
这个怎么实现呢?
来看一下ECDHE + rsa。
  1. 1. ClientHello       → 客户端支持的TLS版本、密码套件、随机数
  2. 2. ServerHello      ← 服务器选择的密码套件、随机数
  3. 3. Certificate      ← 服务器证书(含公钥)
  4. 4. ServerKeyExchange← 服务器的临时ECDH公钥参数(RSA签名)
  5. 5. ClientKeyExchange→ 客户端的临时ECDH公钥参数
  6. 6. 双方计算共享密钥 → 通过ECDH算法生成会话密钥(无需公钥加密)
  7. 7. 切换对称加密     → 后续通信使用AES等对称加密
复制代码
流程是这样的,还是有点模糊。
因为这里临时ECDH公钥参数 这里是明文,不还是会被捕获吗? 不还是可以解析出来吗?
来看一下细节,细节就是客户端有一个临时私钥。

  • 客户端的临时私钥是什么?
临时性:仅在单次TLS会话中生成,会话结束后销毁。
作用:用于密钥交换算法(如ECDHE),与服务器的临时公钥共同生成共享密钥(Pre-master Secret)。
数学关系(以ECDHE为例):
客户端生成临时密钥对:
私钥(d_client):保密,仅客户端知晓。
公钥(Q_client = d_client × G):发送给服务器(G为椭圆曲线基点)。
服务器同理生成临时密钥对(d_server, Q_server)。
来看下具体怎么操作的:

  • ClientHello
客户端发送支持的密码套件和随机数(Client Random),此时尚未生成临时私钥。

  • ServerHello + ServerKeyExchange:
服务器回复随机数(Server Random)和 临时ECDHE公钥(Q_server)

  • 签名(用长期私钥(如 RSA/ECDSA)签名 Q_server,发送给客户端(ServerKeyExchange))
    【私钥d_server服务端留着】。

  • ClientKeyExchange
用公钥验证签名. 这里签名是为了证明Q_server 是从服务端发出来的。
客户端生成临时ECDHE密钥对(d_client, Q_client)。
将 Q_client 发送给服务器(明文传输)。
  1. Shared Secret = d_client × Q_server
复制代码
服务端得到Shared Secret公式为:
  1. Shared Secret = Q_client × d_server
复制代码
因为网络捕获,不知道客户端的d_client也不知道服务的d_server,那么得不到Shared Secret。

  • 生成秘钥
双方用 Shared Secret、Client Random、Server Random 派生对称密钥(如AES密钥)。
因为ECDHE密钥对是临时的,所以以前的会话也就回复不了。
我们这里每次tls的时候,clienthello阶段,每次都需要发送一个公钥,那么我们缓存的意义何在呢?
其实这个clienthello阶段一定会发生,但是参数的改变可能服务端就不需要发送证书:
会话恢复机制:
Session ID(TLS 1.2)
客户端在ClientHello中携带之前缓存的Session ID。
服务器检查Session ID有效性:
如果有效 → 跳过证书发送,直接复用会话密钥。
如果无效 → 回退到完整握手(发送证书)。
Session Ticket(TLS 1.3)
客户端在ClientHello中携带加密的Session Ticket(由服务器上次握手时签发)。
服务器解密Ticket并验证:
如果有效 → 跳过证书发送,直接恢复会话。
如果无效 → 回退到完整握手(发送证书)。
[code]Client                  Server------                  ------ClientHello  ----------->                       ServerHello                       Certificate                       ServerKeyExchange                       ServerHelloDoneClientKeyExchange  ----------->[ChangeCipherSpec]Finished     ----------->                       [ChangeCipherSpec]                       Finished                       NewSessionTicket
您需要登录后才可以回帖 登录 | 立即注册