Skip to content
Published:

理解 Https 加密通信过程的一次脑暴

Table of contents

Open Table of contents

HTTP Prerequisites

HTTP(HyperText Transfer Protocol)被认为不安全,主要原因是它缺乏数据加密和身份验证机制。不安全在于:

  1. 数据明文传输,任何人都可以在数据传输过程中拦截并读取这些数据。这意味着包括用户名、密码、信用卡信息等敏感数据在内的所有信息都可以被第三方截获。

  2. 无身份验证,HTTP 协议没有内置的机制来验证客户端与服务器之间的连接是合法的。这使得攻击者可以假装成目标服务器与客户端通信,窃取或篡改数据。

  3. 易受篡改:由于 HTTP 数据在传输过程中没有加密,也没有任何校验机制,数据容易被中途篡改。攻击者可以在数据传输过程中修改数据,而客户端和服务器无法检测到这种篡改。

  4. 易受各种攻击

    • 中间人攻击:攻击者可以拦截并修改客户端和服务器之间的通信内容。
    • 监听攻击:攻击者可以监听 HTTP 流量,获取敏感信息。
    • 会话劫持:攻击者可以通过拦截会话令牌,冒充用户进行操作。

HTTPS Advantage

HTTPS(HyperText Transfer Protocol Secure)通过在 HTTP 之上添加 SSL/TLS 层来解决这些问题。优势在于:

  1. 数据加密:通过加密传输的数据,防止被第三方截获。
  2. 身份验证:通过 SSL/TLS 证书验证服务器身份,防止中间人攻击。
  3. 数据完整性:通过加密和校验机制,防止数据被篡改。
  4. 隐私保护:通过加密传输数据,保护用户隐私和敏感信息。

SSL/TLS 是啥

SSL 指安全套接字协议(Secure Sockets Layer),首次发布与 1996 年。SSL 的首次发布其实已经是他的 3.0 版本,SSL 1.0 从未面世,SSL 2.0 则具有较大的缺陷(DROWN 缺陷——Decrypting RSA with Obsolete and Weakened eNcryption)。很快,在 1999 年,SSL 3.0 进一步升级,新版本被命名为 TLS 1.0。因此,TLS 是基于 SSL 之上的,但由于习惯叫法,通常把 HTTPS 中的核心加密协议混称为 SSL/TLS

HTTPS 加密过程简化版

回到正题: HTTPS 加密过程可以总结为以下步骤:

  1. 客户端请求 HTTPS 资源
  2. 服务器发送 SSL/TLS 证书
  3. 客户端验证证书
  4. 客户端和服务器通过 TLS 握手协商加密方式和会话密钥
  5. 使用对称会话密钥进行加密通信

理解 HTTPS 加密的脑暴过程

  1. 既然明文不安全,那协商好密钥,对称加密报文如何?

    对称加密密钥🔑是如何协商出来?→ 通过报文的方式直接传输此密钥?→ 之后的通信不还是裸奔 → ❌

  2. 对这个密钥再进行加密呢?

    如何解密这个密钥?→ 还是要传输加密密钥,依然还是会被中间人截获的 → 俄罗斯套娃 → ❌

直接传输密钥无论从哪一端传,看来是不行了 img1

但基于对称加密有着加解密速度快性能高等优点,它也是 HTTPS 最终采用的加密形式,所以我们现在要解决的问题还是,如何协商出同一把密钥用于后续的对称加密呢?

  1. 用非对称加密来加密对称加密密钥🔑呢?

    非对称加密:公钥加密的密文只有私钥可以解密,私钥加密的内容,也只有公钥可以解密。

    1. server 保管好私钥,传输公钥给 client

    2. client 使用从 server 收到的公钥加密对称加密密钥🔑后传给 server

    3. server 使用私钥解密后即可拿到对称加密密钥🔑,这样回答了 1 中的 对称加密密钥🔑是如何协商出来 这一问题

    4. 接下来就可以用对称加密密钥🔑,进行后续的报文传输

    但步骤 1 中 server 怎么把公钥安全地传输给 client 呢?→ 直接传公钥?→ 也会存在被中间人调包的风险 → ❌

    img1

好了,现在只需要解决如何安全的将公钥传输给 client 即可;client 有了安全且可信任的公钥后,用此公钥加密对称加密密钥🔑后发给 server,server 用私钥解密,得到对称加密密钥🔑,后续的通信用此对称加密密钥🔑来对报文进行对称加密。over!

  1. 数字证书来解决传输公钥的安全问题

    1. server 向 CA 申请证书,证书内容包括

      • 证书明文
      • 证书签名:由 CA 的私钥去加密证书摘要(md5(证书明文))得来

      img1

    2. server 传输证书给 client

    3. client 收到来自 server 的证书

      1. 摘要 A = md5(证书明文)
      2. 使用 CA 公钥(在 Root CA 证书(是被操作系统信任的,内置在操作系统上的证书,无需传输)中获得)获得摘要 B
      3. 对比 摘要 A === 摘要 B

      img1

这样,只要摘要对比是一致的,client 就可以认为这个来自 server 的证书是可信任的,而证书中的公钥也是安全的,就可以用这个公钥与 server 进行后续的通讯。

🔔 结束,HTTPS 的加密过程不过如此。over!

白话版总结

HTTPS 无非就是 HTTP + SSL/TLS,而 SSL/TLS 本质上在解决如何协商出安全的对称加密密钥🔑这一问题,以利用此密钥进行后续的通讯;

如何协商出安全可信任的对称加密密钥🔑?答案是 server 和 client 之间,使用非对称加密来传输对称加密密钥🔑

  1. server 传输非对称加密的公钥给浏览器 (❌)
  2. client 用此公钥加密对称加密密钥🔑后,传输给 server;
  3. server 用非对称加密的私钥解密,得到对称加密密钥🔑

但由于 1 步骤是不安全的,server 传输公钥呢的最终版为:

  1. server 申请 CA 证书
    1. 提交公钥、组织信息、个人信息(域名)等信息并申请认证(注意 server 私钥不传,用于后续的步骤 6)
    2. CA 机构通过多种手段验证申请者提供信息的真实性,如组织是否存在、企业是否合法,是否拥有域名的所有权等;
    3. 如信息审核通过,CA 会向申请者签发证书:
      • 申请者公钥
      • 申请者的组织信息和个人信息、签发机构 CA 的信息、有效时间、证书序列号等信息的明文
      • 签名(= CA 的私钥对信息摘要进行加密,可由后续步骤 3 解密)
  2. server 传输 CA 颁发的证书(提交 server 公钥,(注意 server 私钥不传,用于后续的步骤 5))给 client
  3. client 收到证书后使用内置 CA 证书中的公钥(注意该公钥与来自 server 的 CA 证书中的公钥不是一回事儿)来解密签名
  4. 校验通过,即可认为来自 server 的 CA 证书中的公钥的可信任的
  5. 用 CA 证书中的公钥加密对称加密密钥🔑,传输给 server
  6. server 用密钥解密,得到对称加密密钥🔑
  7. 对称加密密钥🔑来进行后续通讯的过程

一些补充🧐

  1. charles 是怎么抓包的

    HTTPS 既然是加密的, charles 为啥能抓到明文的包呢,其实就是用了证书调包这一手法,我们在用 charles 抓 HTTPS 的包之前我们先要安装 charles 的证书;这个证书里有 charles 的公钥,这样的话 charles 就可以将 server 传给 client 的证书调包成自己的证书,client 拿到后就可以用你安装的 charles 证书来验签等,验证通过之后就会用 charles 证书中的公钥来加密对称密钥了

  2. 私钥加密其实这个说法其实并不严谨,准确的说私钥加密应该叫私钥签名,因为私密加密的信息公钥是可以解密的,而公钥是公开的,任何人都可以拿到,用公钥解密叫做验签,本文为了易于理解,暂时不管这些

总结:一次标准的 HTTPS 请求过程

  1. TCP 三次握手:

    • 客户端向服务器发送 SYN 包:客户端发送一个 SYN 包,表示请求建立连接。
    • 服务器回应 SYN-ACK 包:服务器收到 SYN 包后,回复一个 SYN-ACK 包,表示同意建立连接。
    • 客户端回应 ACK 包:客户端收到 SYN-ACK 包后,回复一个 ACK 包,表示连接建立成功。
  2. TLS 握手:

    • 客户端发送 ClientHello:客户端发送 ClientHello 消息,包含支持的加密算法和其他加密设置。
    • 服务器回应 ServerHello:服务器发送 ServerHello 消息,包含选择的加密算法和服务器证书。
    • 客户端验证服务器证书:客户端验证服务器证书的有效性。
    • 客户端发送密钥交换消息:客户端生成一个对称加密的密钥,并用服务器的公钥加密发送给服务器。
    • 服务器解密密钥交换消息:服务器使用自己的私钥解密得到的密钥。
    • 双方使用对称密钥加密通信:后续通信使用对称加密。

每个 HTTPS 连接开始时都会进行一次 TCP 握手和 TLS 握手,但通过持久连接和 HTTP/2 或 HTTP/3 的复用机制,可以在一个连接上处理多个请求,从而减少频繁握手的开销。