HTTPS全解析:从证书签发到TLS握手优化

发布于:2025-05-13 ⋅ 阅读:(16) ⋅ 点赞:(0)

HTTPS(超文本传输安全协议 本质上是HTTP的安全版本。标准的HTTP协议仅规范了客户端与服务器之间的通信格式,但所有数据传输都是明文的,容易被中间人窃听和篡改。HTTPS通过加密传输数据解决了这一安全问题。

HTTPS可以理解为"HTTP+TLS/SSL"。虽然名称中仍保留"SSL"(安全套接层),但现代HTTPS实际使用的是更先进的TLS(传输层安全)协议。目前最新的版本是TLS/1.3。

协议发展史:
SSL 1.0 → SSL 2.0 → SSL 3.0 → TLS 1.0 → TLS 1.1 → TLS 1.2 → TLS 1.3

如今主流浏览器和服务器都已淘汰不安全的SSL协议,全面支持TLS协议。TLS/1.3在安全性、性能和隐私保护方面都有显著提升。

一、CA证书

虽然,TLS或者SSL加密解决了服务端与客户端之间交流信息被窥探的问题,但是,我们仍无法保证客户在输入域名时输入的是正确域名,比如,我想访问CSDN(www.csdn.net),会不会多输一个字符(www.csdnn.net),这样就可以伪造相似的域名来给客户访问,当客户输错时就进入到了错误的网站,

为了解决这个问题,服务端需要申请SSL证书(现代使用的都是TLS协议,但证书仍然习惯称为"SSL证书",证证书本身不依赖SSL或者TLS,它只是用于身份验证和密钥交换的文件,由于SSL最早使用证书,所以"SSL证书"成了通用称呼)来证明这个域名就是大家熟知的CSDN网站。例如我的浏览器就拿到了这个证书

请添加图片描述

数字证书包含以下关键信息:

  1. 颁发对象的基本信息(如域名)
  2. 网站的公钥
  3. 颁发机构(CA)的数字签名
  4. 有效期等元数据

当用户通过HTTPS(默认端口443)访问网站时,浏览器会自动验证服务器提供的证书:

  • 检查证书是否由受信任的CA签发
  • 验证证书中的域名与实际访问的域名是否匹配
  • 确认证书是否在有效期内

通过这套机制,即使用户输入错误的域名,只要该域名没有合法的证书,浏览器就会显示安全警告,有效防止用户误入钓鱼网站。

二、TLS握手过程

TLS/1.2

正常的TCP三次握手是不变的,TCP三次握手如下所示:

请添加图片描述

但是TLS握手需要更多的步骤,在TCP链接建立以后:

请添加图片描述

  1. 客户端发送 Client Hello 消息

    • 客户端向服务器发起握手,并告知支持的加密参数。
    • 包含内容
      • TLS 版本(如 TLS 1.2)。
      • 客户端随机数(Client Random)(用于后续密钥计算)。
      • 支持的加密套件(Cipher Suites)(如 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)。
      • 支持的压缩算法(现代TLS通常不使用压缩)。
  2. 服务端发送 Server Hello 消息

    • 服务器确认加密参数,并生成服务器随机数。
    • 包含内容
      • TLS 版本(如 TLS 1.2)。
      • 服务端随机数(Sever Random)(用于后续密钥计算)。
      • 支持的加密套件(Cipher Suites)(如 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)。
      • 会话 ID(Session ID)(用于会话恢复,可选)。
  3. 服务端发送 Certificate 消息

    • 服务器发送自己的证书,供客户端验证身份。
    • 包含内容
      • 服务器的 X.509 证书(包含公钥、域名、颁发机构等信息)。
      • 证书链(Certificate Chain)(中间CA证书,帮助客户端验证信任链)。
    • 客户端需验证
      • 检查证书是否过期。
      • 检查域名是否匹配(防止钓鱼攻击)。
      • 检查颁发机构(CA)是否受信任(如 DigiCert、Let’s Encrypt)。
  4. 服务端发送 Server Key Exchange 消息

  • 如果使用 ECDHE 或 DHE 等密钥交换算法,服务器会发送临时公钥。
  • 包含内容
    • DH/ECDH 参数(如椭圆曲线名称、临时公钥)。
    • 签名(证明参数未被篡改)。
  1. 服务端发送 Server Hello Done 消息
    • 告知客户端服务器握手信息发送完毕,等待客户端响应。
  2. 客户端发送 Client Key Exchange 消息
    • 客户端生成 预主密钥(Pre-Master Secret) 并加密发送给服务器。
    • 包含内容
      • 加密的预主密钥(使用服务器证书中的公钥加密,或者用第4步发送的临时公钥进行加密)
      • 如果是 RSA 密钥交换,直接发送加密的预主密钥。
      • 如果是 ECDHE/DHE,客户端也发送自己的临时公钥。
  3. 服务端和客户端发送 Change Cipher Spec 以及 Finished 消息
    • 通知服务器,后续通信将使用协商的密钥加密。
  4. 后续通信使用双方沟通好的秘钥进行通信,即对称加密,秘钥为(客户端随机数 + 服务端随机数 + 预主秘钥)

TLS/1.3

TLS/1.3 的整个握手过程发生了一些改变

  • 合并消息Server HelloCertificateServer Key Exchange 合并为一条响应。
  • 删除冗余步骤:移除 Change Cipher Spec(加密切换隐含在握手逻辑中)。
总结

1.2协议的过程

在这里插入图片描述

1.3协议的过程

在这里插入图片描述

三、TLS/1.3 升级了什么

前向保密

TSL 1.2 中的加密措施主要是 RSA 和 DH 算法,DH算法可以每次都使用新的随机数,因此不存在前向保密的问题,即使从以往的信息中破解出了私钥,那也只是那一次通信的私钥,而RSA存在前向保密问题,因为其私钥和公钥都是静态的,那么一旦私钥被破解,以前通信的消息都会被破解。 其实不使用临时随机数的DH算法也有这个问题。因此静态的RSA和DH秘钥交换算法在TLS/1.3中被移除了。

  • TLS/1.2:支持非前向安全的 RSA 密钥交换。
  • TLS/1.3强制使用 ECDHE,即使私钥泄露,历史会话也无法解密。

参数组合

那是不是使用非静态参数就安全了?其实这就相当于我们选择不改密码和经常改密码,经常改密码当然是更加安全的。但实际上一些主机并不支持新版本的TLS,甚至只支持SSL。TLS/1.2 协议是支持版本降级的,因此在这些较旧的主机上必须通过版本降级来通信。

同时,DH算法参数(P与G)是通过服务器来选择的,可以有很多选择,虽然DH算法破解难度大,但是DH并不是所有参数都安全。

TLS/1.2 协议在创建连接时是明文的,因此可能被黑客截获,截获后可以给服务端发送假的 Clien Hello 消息,造成服务端协议降级。虽然1024bit的DH协议很安全,那降级成512bit破解难度就降低不少了。

因此TLS/1.3干脆放弃了DH算法中很多弱参数选择,并对参数进行了限制。

密码套件

TLS/1.2 支持的密码套件有:

TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
TLS_PSK_WITH_AES_256_GCM_SHA384
TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256

其格式为

TLS_[密钥交换算法]_[身份验证算法]_WITH_[加密算法]_[哈希算法]

这仅是常见的密码套件组合,其实际可选用的密码套件组合更多,所以在建立加密通信之前必须协商需要使用的密码套件组合。

在TLS/1.3 协议中,仅建议五种密码套件:

TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_CCM_SHA256
TLS_AES_128_CCM_8_SHA256

密码套件的格式变为

TLS_[对称加密算法]_[哈希算法]

看起来就更简单了,代价是只支持三种密钥交换方式 (EC)DHEPSK-onlyPSK ith (EC)DHE

TLS/1.3 中参数就少了很多,速度也快了很多。也正是因为客户端一开始就可以发送协商参数,因此TLS/1.3 相较于 TLS/1.2 少了 1-RTT

恢复会话 (0-RTT)

客户端和服务端此前已完成完整握手,并缓存了会话密钥。 客户端 → 服务端 Client Hello + 0-RTT 数据 就可以直接恢复之前的会话。

但这个技术存在一定问题,给了黑客一定的可乘之机,黑客可以截获客户端恢复会话的消息,在多次发送给服务端,那么原本只转账1元,现在就转了n元。

对比

特性 TLS/1.2 TLS/1.3
握手耗时 2-RTT 1-RTT(默认),0-RTT(可选)
密钥交换 支持 RSA(不安全)、ECDHE 仅 ECDHE(强制前向安全)
加密算法 AES-CBC、RC4(不安全) 仅 AES-GCM、ChaCha20
握手消息加密 Finished 后加密 除 Hello 外全部加密
降级攻击防护 较弱 强制版本确认

四、好像并不需要CA…吗?

上述的Https握手阶段我们可以发现,似乎可以跳过CA这个过程,但并非如此,这样的话无法解决中间人的问题

请添加图片描述

客户端在通信时一直在于中间人通信,中间人在截获消息后再发送给服务端。核心在于,在TLS握手阶段,中间人劫持了流量,伪装成了服务端,客户端认为自己与服务端建立了加密通信,但是其实是与中间人建立了加密通信,那加了个寂寞。

所以CA还是需要的,这样一开始你不需要与服务端建立通信,而是与CA建立通信,CA将服务端的公钥保存起来,当你需要的时候再一同生成CA证书发给你,但是…我怎么确定CA是真的呢???

确定CA证书为真就需要数字签名,CA会将网站的各种信息包括网站的公钥整合成CA证书,并通过自己的私钥对证书的哈希值进行加密生成数字签名,数字签名也在这个CA证书中,CA证书部署在服务端的服务器中,好的,那么我们客户端在拿到这个CA证书时就可以通过公钥来解密,并与证书的哈希值对比,相同的话,就是原网站,不同就是被劫持。但是这个CA的公钥,它在CA的服务器上啊,我怎么确定这个CA不是中间人伪造的,这很有可能啊,这就需要再给这个CA机构的网站加一个证书…麻了,没完了。

最终极的解决方案是证书链,或者可以认为是一个树,他有个根,服务端的证书由中间CA机构发,中间CA机构的证书由根CA发,根CA已经无法验证了,那么就直接内置在用户的设备中,操作系统和浏览器都预置了全球可信根CA的证书(含公钥)。

总结来讲:

HTTPS通过 数字证书链预置信任锚 解决这个问题:

  1. 证书签发流程
    • 网站向CA提交信息(域名、公钥等)。
    • CA验证网站身份后,用自己的私钥对网站信息(含公钥)签名,生成数字证书。
    • 网站将证书部署到服务器。
  2. 客户端验证流程
    • 客户端收到证书后,用CA的公钥验证签名,确认证书未被篡改。
    • 进一步验证证书中的域名是否匹配、有效期是否合法。
  3. 信任锚:预置根证书
    • 操作系统和浏览器预置了全球可信根CA的证书(含公钥)。
    • 这些根证书是信任链的起点(如微软、苹果、Mozilla维护的根证书列表)。
    • 若中间人伪造CA证书,由于客户端未预置其根证书,验证会失败。

五、Https的核心优势

数据加密传输

  • 采用 TLS/SSL 协议对通信内容进行端到端加密
  • 有效防止中间人攻击(MITM)、流量劫持等安全威胁
  • 保护用户敏感信息(如密码、支付信息、个人隐私数据)

身份真实性验证

  • 通过 CA 颁发的数字证书验证网站真实身份
  • 防止钓鱼网站和域名仿冒(如将 taobao.com 仿冒为 taoba0.com)
  • 浏览器会明确展示网站认证信息(地址栏锁形图标)

数据完整性保护

  • 使用消息认证码(MAC)确保传输内容不被篡改

  • 防止运营商劫持插入广告等行为

  • 有效防止中间人攻击(MITM)、流量劫持等安全威胁

  • 保护用户敏感信息(如密码、支付信息、个人隐私数据)


网站公告

今日签到

点亮在社区的每一天
去签到