可以参考B站的一个视频,把TLS/SSL的连接建立过程降解的非常透彻。配合这篇博客食用更佳。一遍不懂请多看几遍,很有用!

1 说明

1.1 对称加密的和非对称加密

在数字加密算法中,通过可划分为对称加密和非对称加密。

什么是对称加密?

  1. 在对称加密算法中,加密和解密使用的是同一把钥匙,即:使用相同的密匙对同一密码进行加密和解密;

  2. 加密过程如下:

加密:原文 + 密匙 = 密文

解密:密文 - 密匙 = 原文

  1. HTTPS是建立在SSL/TCL协议之上,而SSL/TLS是建立在TCP协议之上。
    所以HTTPS的建立过程可以分解为TCP + SSL/TLS + HTTP协议依次建立连接的过程
  2. 优点:算法简单,加密解密容易,效率高,执行快。
  3. 缺点:相对来说不算特别安全,只有一把钥匙,密文如果被拦截,且密钥也被劫持,那么,信息很容易被破译。

非对称加密

  1. 对称加密是使用的同一把密匙进行加密和解密。那么,非对称加密自然是使用不同的密钥进行加密和解密。非对称加密有两个钥匙,及公钥(Public Key)和私钥(Private Key)。公钥和私钥是成对的存在,如果对原文使用公钥加密,则只能使用对应的私钥才能解密;因为加密和解密使用的不是同一把密钥,所以这种算法称之为非对称加密算法。 非对称加密算法的密匙是通过一系列算法获取到的一长串随机数,通常随机数的长度越长,加密信息越安全。通过私钥经过一系列算法是可以推导出公钥的,也就是说,公钥是基于私钥而存在的。但是无法通过公钥反向推倒出私钥,这个过程的单向的。

  2. 优点:安全,即使密文被拦截、公钥被获取,但是无法获取到私钥,也就无法破译密文。作为接收方,务必要保管好自己的密钥。

  3. 缺点:加密算法非常复杂,安全性依赖算法与密钥,而且加密和解密效率很低,一般用于网站的SSL证书的验证

2 SSL和TLS

2.1 什么是数字证书?

数字证书有点类似于我们的居民身份证,只是数字证书是基于互联网通信的,用于标记通信双方身份的一种方式

数字证书绑定了公钥及其持有者的真实身份,它类似于现实生活中的居民身份证,所不同的是数字证书不再是纸质的证照,而是一段含有证书持有者身份信息并经过认证中心审核签发的电子数据,广泛用在电子商务和移动互联网中。

服务端可以向证书颁发机构CA申请证书,以避免中间人攻击(防止证书被篡改)。证书包含三部分内容:tbsCertificate(to be signed certificate)待签名证书内容、证书签名算法和CA给的数字签名(使用证书签名算法对tbsCertificate进行哈希运算得到哈希值,CA会用它的私钥对此哈希值进行签名,并放在签名部分)。签名是为了验证身份。

https://pic3.zhimg.com/80/v2-d50e9b263bed9456ce67a3cf18dff666_720w.jpg

2.2 SSL和TLS的关系

SSL是TLS的前身。由于HTTPS的推出受到了很多人的欢迎,在SSL更新到3.0时,IETF(The Internet Engineering Task Force - 互联网工程任务组)对SSL3.0进行了标准化,并添加了少数机制(但是几乎和SSL3.0无差异),标准化后的IETF更名为TLS1.0(Transport Layer Security 安全传输层协议),可以说TLS就是SSL的新版本3.1,并同时发布“RFC2246-TLS加密协议详解”,如果想更深层次的了解TLS的工作原理可以去RFC的官方网站:http://www.rfc-editor.org,搜索RFC2246即可找到RFC文档! ——以上就是历史背景

因为SSL名气更大,所以我们就经常把他们混着用;
目前绝大部分浏览器都不支持SSL,而支持TLS

3 HTTPS建立连接的过程

3.1 首先正常的TCP三次握手是不变的

  1. 第一次握手:客户端向服务端发起建立连接请求,客户端会随机生成一个起始序列号x,客户端向服务端发送的字段中包含标志位SYN=1,序列号seq=x。第一次握手前客户端的状态为CLOSE,第一次握手后客户端的状态为SYN-SENT。此时服务端的状态为LISTEN
  2. 第二次握手:服务端在收到客户端发来的报文后,会随机生成一个服务端的起始序列号y,然后给客户端回复一段报文,其中包括标志位SYN=1,ACK=1,序列号seq=y,确认号ack=x+1。第二次握手前服务端的状态为LISTEN,第二次握手后服务端的状态为SYN-RCVD,此时客户端的状态为SYN-SENT。(其中SYN=1表示要和客户端建立一个连接,ACK=1表示确认序号有效)
  3. 第三次握手:客户端收到服务端发来的报文后,会再向服务端发送报文,其中包含标志位ACK=1,序列号seq=x+1,确认号ack=y+1。第三次握手前客户端的状态为SYN-SENT,第三次握手后客户端和服务端的状态都为ESTABLISHED。

https://pic3.zhimg.com/v2-ff043808f0b6a04683e23e73021f7ff2_r.jpg

3.2 建立TLS/SSL连接

协商加密算法阶段:

  1. 客户端会在第三次TCP握手或者在新发送的TCP报文段中发送一个 client hello报文给服务端,报文段中包含客户端支持的所有SSL加密算法(也称加密套件)和TLS/SSL版本以及所要访问的域名(服务器需要通过域名返回域名对应的TSL证书),同时会包含一个生成的第一随机数

[外链图片转存中…(img-eGCUj5eV-1639744405270)]

  1. 服务端收到SSL的hello报文后,会发送server hello报文进行响应,报文段中包含选中的加密算法和TSL版本,同时也包括随机生成的第二随机数

image.png

证书验证阶段(使用非对称加密):
3. 接着服务器会再依次发送两个报文给客户端,第一个报文中包含了服务端证书的相关信息,第二个报文中包含公钥信息;如果服务器也需要客户端的证书则会在第二个报文中声明,比如在登录网上银行的场景中则有这个需求
这样客户端浏览器就可以根据自己的证书列表来确认这个服务器是否可信

image.png

第一个报文

[外链图片转存中…(img-8PZxv59M-1639744405277)]

第二个报文
  1. 客户端使用证书的认证机构CA公开发布的RSA公钥对该证书进行验证,下图表明证书认证成功。
    https://pic1.zhimg.com/v2-112028d417bff9f096dced68b2096c58_r.jpg
    首先,要想了解清楚解密过程,就必须先搞懂数字签名的制作过程,数字签名的制作过程:
  • 使用CA证书签名算法对证书内容(待签名证书内容)进行hash。
  • 对hash后的值用CA自己的私钥加密,得到数字签名。

浏览器验证过程:

  • 拿到证书,得到证书内容、证书签名算法和数字签名。
  • 用CA机构的公钥对数字签名解密(由于是浏览器信任的机构,所以浏览器会保存它的公钥)。
  • 用证书里的签名算法对证书内容进行hash。
  • 比较解密后的数字签名和对证书内容hash后的哈希值,相等则表明证书可信,否则即不可信,拒绝对该服务器的访问。自此便完成了网站的安全认证工作
  1. 服务端发送server hello done报文给客户端,表示服务器已经把公钥和证书信息传送完毕
    image.png

建立会话密钥阶段(为使用对称加密传输数据做做铺垫):

  1. 客户端发送client key exchange报文给服务端,报文中包含随机生成的第三个随机数,也称为预主密钥,在装入报文之前,会用公钥加密;同时客户端也会利用第一,第二和第三随机数生成会话密钥。
    image.png

  • 服务端收到客户端的报文后,会使用私钥进行解密,这样就得到了预主密钥,而且只有客户端和服务端知道这个预主密钥,没有其他人知道(因为预主密钥一旦被公钥加密,只能由私钥加密,反之同理,所以除非私钥泄露了,否则没有人会知道预主密钥)。
  • 得到预主密钥后,服务端会使用第一随机数,第二随机数和预主密钥也生成一个会话密钥,这个会话密钥和客户端生成的会话密钥是一样的
  1. 至此TSL连接建立完成,可以开始传输数据,并且使用同一个私钥密钥来加解密(也称为对称加密)。

3.3 建立HTTPS连接

浏览器和服务端只需要根据响应的HTTP连接规则(包括长连接还是短连接,流水线和非流水线连接)实现数据的加密传输

4 面试必问

4.1 为什么整个SSL的连接建立过程不全部使用非对称加密?(字节后端开发二面)

结合1.1的解析,可知非对称加密算法十分复杂,加密解密时间长,效率低,因此我们只在TSL连接建立时才使用,后面的数据传输环节统一使用对称加密,这样既能保证效率,又能极大的增强安全性。

4.2 SSL证书的校验过程(字节后端开发二面)

SSL(现在更常称为TLS)证书的校验是SSL/TLS握手过程的重要组成部分。这个校验确保与客户端交互的服务器是它声称的服务器,并且其证书是受信任的证书颁发机构(CA)签发的。下面是SSL/TLS证书的校验过程:

  1. 客户端发送ClientHello:在TLS握手的开始,客户端发送一个ClientHello消息,包括它所支持的协议版本、加密套件等。

  2. 服务器响应ServerHello:服务器响应ServerHello消息,选择一个客户端也支持的协议版本和加密套件,并发送自己的SSL证书。

  3. 客户端验证证书

    • 过期检查:客户端首先检查证书的有效期,确保它还没有过期。
    • 证书颁发机构检查:客户端查看证书是由哪个CA签发的,并在其内置的受信任的CA列表中检查这个CA。如果证书不是由受信任的CA签发的,客户端会显示一个警告。
    • 域名检查:客户端检查证书上的Common NameSubject Alternative Name字段,确保其与要访问的网站的域名匹配。
    • 证书撤销检查:有两种主要的技术用于检查证书是否被撤销:CRL(证书撤销列表)和OCSP(在线证书状态协议)。这步确保证书仍然是有效的并且没有被撤销。
  4. 服务器密钥交换:基于所选的加密套件,服务器可能会发送一个密钥交换消息,这通常涉及到公钥加密技术。

  5. 客户端生成预主密钥:客户端生成一个预主密钥并使用服务器证书中的公钥加密它,然后发送给服务器。

  6. 双方生成会话密钥:客户端和服务器都使用这个预主密钥以及在之前的握手过程中交换的信息来生成会话密钥。

  7. 客户端发送Finished消息:客户端使用上一步生成的会话密钥加密一个Finished消息并发送给服务器。

  8. 服务器响应Finished消息:服务器解密客户端的消息,验证其内容,然后使用会话密钥加密另一个Finished消息并发送给客户端。

  9. 加密的会话开始:此时,客户端和服务器已经成功地交换和验证了证书,双方开始加密的会话。

在这整个过程中,证书的验证确保客户端与其预期的服务器进行通信,而不是中间人。这为客户端和服务器之间的通信提供了身份验证和数据加密。

4.3 ## 假设这个证书不是由一个可信的人发的,但是这个证书本身是合法的,客户端怎么知道哪些证书可以信任,哪些不能信任?(字节后端开发二面)

当一个证书不是由一个受信任的证书颁发机构(CA)签发的时,即使它在技术上是合法的(比如它是正确地签名的、没有过期等),大多数客户端还是不会默认地信任这个证书。这是因为证书的信任并不仅仅基于证书本身的有效性,而是基于谁签发了这个证书。以下是详细解释:

  1. 受信任的CA列表:如前所述,客户端(例如浏览器或操作系统)内置有一个受信任的CA列表。只有在这个列表中的CA签发的证书会被默认信任。这个列表的维护是非常严格的,只有经过深入审核的CA才会被加入。

  2. 合法但不受信任的证书:一个证书可能是完全合法的(比如它是有效的、未过期的、并且正确地签名的),但如果它不是由客户端已知的受信任的CA签发的,客户端还是不会信任它。在这种情况下,当用户试图访问使用这样证书的网站时,浏览器通常会显示一个警告,告诉用户这个证书不能被信任。

  3. 手动导入证书:尽管默认情况下浏览器或其他客户端可能不信任某个证书,但用户通常有选项手动导入并信任这个证书。这在开发或测试环境中是很常见的,因为开发者可能使用自签名证书而不是由公认CA签发的证书。

  4. 私有CA或企业CA:在某些企业或组织环境中,可能存在私有的或企业级的CA,这些CA签发的证书仅在这个组织或企业内部受信任。为了确保员工或内部用户的设备信任这些证书,企业IT部门可能会将这些私有CA的根证书部署到组织内的所有设备上。

总的来说,证书的信任决定不仅仅基于证书本身的合法性,而是基于谁签发了这个证书。这是一个安全机制,确保只有经过验证并被认为是可信的实体签发的证书才会被客户端信任。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐