计网基础-HTTPS

loading 2023年01月29日 101次浏览

内容源于小林coding的图解计网博客,加入了自己的总结归纳。

1. 和HTTP的区别

  1. 安全性
    1. HTTP明文传输,存在安全风险
    2. HTTPS在TCP传输层和HTTP应用层间加入了SSL/TLS安全协议,使得报文能够加密传输
  2. 建立连接
    1. HTTP通过TCP三次握手后即可进行HTTP报文传输
    2. HTTPS进行三次握手后还需要进行SSL/TLS握手,才能进行加密报文传输
  3. 端口
    1. HTTP默认端口80
    2. HTTPS默认端口443
  4. 证书
    1. HTTP不需要
    2. HTTPS需要向CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的

总得来说:
建立连接时候: https 比 http多了 TLS 的握手过程
传输内容的时候: https 会把数据进行加密,通常是对称加密数据

2. HTTPS如何实现安全加密?

HTTP由于是明文传输,因此主要存在着被窃听,篡改,冒充等等风险,而HTTPS通过加入SSL/TLS协议,实现了以下功能:

  • 信息加密: 通过混合加密的方式实现信息的机密性,解决了窃听的风险。
  • 校验机制: 通过摘要算法的方式来实现完整性,它能够为数据生成独一无二的「指纹」,指纹用于校验数据的完整性,解决了篡改的风险。
  • 身份证书: 将服务器公钥放入到数字证书中,解决了冒充的风险

2.1 混合加密(解决窃听问题)

通过混合加密的方式可以保证信息的机密性,解决了窃听的风险。

HTTPS 采用的是对称加密非对称加密结合的「混合加密」方式:

对称加密:加密和解密使用同一个密钥,优点是运算速度快,缺点是必须保密密钥,无法做到安全的密钥交换。
非对称加密: 加密和解密使用两个密钥,优点是可以做到安全的密钥交换,缺点是速度慢。

公钥和私钥是在非对称加密中通过加密算法得到的一个密钥对。
公钥可对会话进行加密、验证数字签名,只有使用对应的私钥才能解密会话数据,从而保证数据传输的安全性。(也可以公钥解密,私钥加密)
公钥是密钥对外公开的部分,私钥则是非公开的部分,由用户自行保管。

  • 在通信建立前采用非对称加密的方式交换「会话秘钥」,后续就不再使用非对称加密。
  • 在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据。

2.2 摘要算法 + 数字签名(解决篡改问题)

为了保证传输的内容不被篡改,我们需要对内容计算出一个「指纹」,然后同内容一起传输给对方。

对方收到后,先是对内容也计算出一个「指纹」,然后跟发送方发送的「指纹」做一个比较,如果「指纹」相同,说明内容没有被篡改,否则就可以判断出内容被篡改了。

那么,在计算机里会用摘要算法(哈希函数)来计算出内容的哈希值,也就是内容的「指纹」,这个哈希值是唯一的,且无法通过哈希值推导出内容。

通过哈希算法可以确保内容不会被篡改,但是并不能保证「内容 + 哈希值」不会被中途一起替换掉,因为这里缺少对客户端收到的消息是否来源于服务端的证明。

为了避免被整个替换掉的情况,计算机采用非对称加密解决。

公钥加密,私钥解密。 用来确认接收者(解密者)的身份安全。保证内容传输的安全,因为被公钥加密的内容,其他人是无法解密的,只有持有私钥的人,才能解密出实际的内容;
私钥加密,公钥解密。 用来确认发送者(加密者)的身份安全。保证了消息不会被冒充,因为私钥是不可泄露的,如果公钥能正常解密出私钥加密的内容,就能证明这个消息是来源于持有私钥身份的人发送的。

因此,计算机就可以利用私钥加密,公钥解密的方式来确认消息是否被替换过,被私钥加密过的哈希值被称为数字签名

私钥是由服务端保管,然后服务端会向客户端颁发对应的公钥。 如果客户端收到的信息,能被公钥解密,就说明该消息是由服务器发送的。

2.3 数字证书(解决冒充问题)

2.2中我们通过摘要算法生成哈希值保证了信息不被篡改,通过数字签名保证信息和哈希值不会被一起替换掉。但是这又产生了一个问题,万一数字签名里的公钥和私钥也是被伪造的呢? 用自己伪造的公钥私钥将真正的替换掉,那么毫无疑问也是可以实现公钥私钥配对的。

因此,需要一个机构来存档真正的公钥,也就是数字证书认证机构(CA),机构用它们自己的私钥对服务器的公钥做一个数字签名,然后将「个人信息 + 公钥 + 数字签名」打包成一个数字证书,也就是说这个数字证书包含服务器的公钥。

这样,下次请求时,服务器不仅会用自己的私钥加密哈希值成数字签名,还会把这个数字证书也一起发送给客户端,客户端拿到数字证书后,去对应的机构检查这个数字证书是否合法,如果检测通过,那么就能证明这个公钥并不是被伪造的。

总结一下流程:

  1. 服务器注册公钥到CA,CA通过CA私钥服务器公钥数字签名,打包成数字证书
  2. 服务器将数字证书发给客户端,客户端通过CA公钥去确认数字证书真实性
  3. 确认真实性完毕后,从数字证书中获得服务器公钥,把报文信息用服务器公钥加密并发送,并生成会话密钥。
  4. 服务端接收到报文后,通过服务端私钥进行解密,同时也生成会话密钥。(因为算法是一样的,所以生成的会话密钥也是一样的。)
  5. 这么一来会话密钥就成功协商生成了,接下来客户端采用会话密钥来加密所需要传送的报文,服务端也用会话密钥来解密

具体流程见下一章节的TLS握手过程

3. HTTPS是如何建立连接的(TLS握手)

SSL/TLS协议基本流程:

  • 客户端向服务器索要并验证服务器的公钥
  • 双方协商生产「会话秘钥」
  • 双方采用「会话秘钥」进行加密通信

前两步也就是SSL/TLS的建立过程,也称为TLS握手。

TLS握手涉及四次通信,这里大致讲解一下基于RSA算法的TLS握手过程

1. ClientHello
由客户端向服务器发起加密通信请求,主要发送如下信息:

  • 客户端支持的 TLS 协议版本
  • 客户端生成的随机数(Client Random),后面用于生成「会话秘钥」条件之一
  • 客户端支持的密码套件列表,如 RSA 加密算法

2. SeverHello
服务器收到客户端请求后,发出响应,响应的主要内容如下:

  • 确认 TLS 协议版本,如果浏览器不支持,则关闭加密通信
  • 服务器生成的随机数(Server Random),也是后面用于生产「会话秘钥」条件之一
  • 确认密码套件列表,如 RSA 加密算法
  • 服务器的数字证书

3. 客户端回应
客户端收到服务器回应后,首先通过浏览器或者操作系统中的 CA 公钥确认服务器的数字证书的真实性

如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文,向服务器发送如下信息:

  • 一个随机数(pre-master key),该随机数会被服务器公钥加密。
  • 加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信
  • 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供服务端校验。

上面第一项的随机数是整个握手阶段的第三个随机数,会发给服务端,所以这个随机数客户端和服务端都是一样的。

服务器和客户端有了这三个随机数(Client Random、Server Random、pre-master key),接着就用双方协商的加密算法,生成本次通信的会话秘钥

4. 服务器的最后回应
服务器收到三个随机数后,通过协商好的加密算法,计算出本次通信的会话密钥

然后,向客户端回复信息:

  • 加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信
  • 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验。

至此,整个TLS握手过程结束,接下来,客户端和服务器进行加密通信,通信就是普通的HTTP通信,只不过通过上面生成的会话密钥加密内容

4. HTTPS一定安全可靠吗?

假设这么一个场景:客户端通过浏览器向服务端发起 HTTPS 请求时,被「假基站」转发到了一个「中间人服务器」,于是客户端是和「中间人服务器」完成了 TLS 握手,然后这个「中间人服务器」再与真正的服务端完成 TLS 握手。

从客户端的角度看,其实并不知道网络中存在中间人服务器这个角色。那么中间人就可以解开浏览器发起的 HTTPS 请求里的数据,也可以解开服务端响应给浏览器的 HTTPS 响应数据。相当于,中间人能够 “偷看” 浏览器与服务端之间的 HTTPS 请求和响应的数据。

但是要发生这种场景是有前提的,前提是用户点击接受了中间人服务器的证书。

如果用户执意点击「继续浏览此网站」,相当于用户接受了中间人伪造的证书,那么后续整个 HTTPS 通信都能被中间人监听了。

5. HTTPS的应用数据如何保证完整性?

我们上面提到了TLS握手协议,TLS还有另外一个协议称为TLS记录协议,在通信过程中主要负责消息(HTTP 数据)的压缩,加密及数据的认证。

  • 首先,消息被分割成多个较短的片段,然后分别对每个片段进行压缩
  • 接下来,经过压缩的片段会被加上消息认证码(MAC 值,这个是通过哈希算法生成的),这是为了保证完整性,并进行数据的认证;与此同时,为了防止重放攻击,在计算消息认证码时,还加上了片段的编码
  • 再接下来,经过压缩的片段再加上消息认证码会一起通过对称密钥进行加密
  • 最后,上述经过加密的数据再加上由数据类型、版本号、压缩后的长度组成的报头就是最终的报文数据。

记录协议完成后,最终的报文数据将传递到传输层(TCP)进行传输。

6. HTTPS如何优化

HTTPS相较于HTTP提高了安全性的同时也带来了性能损耗,因为它多了一个TLS握手的过程,目的是为了通过非对称加密握手协商出对称加密密钥,接着后续的应用数据传输都会用对称加密密钥来加密/解密。

为了减少性能损耗,我们可以通过多个角度来优化 HTTPS。

主要要优化两个阶段:

  1. TLS握手
  2. 握手完成后的对称加密报文传输

6.1 硬件优化

如题,这是最快最强的优化方式。

6.2 软件优化

即升级软件,也比较简单粗暴吧,但是看似简单的软件升级,对于有成百上千服务器的公司来说,软件升级也跟硬件升级同样是一个棘手的问题,因为要实行软件升级,会花费时间和人力,同时也存在一定的风险,也可能会影响正常的线上服务。

6.3 协议优化

6.3.1 更换密钥交换算法

协议的优化就是对「密钥交换过程」进行优化。

上面学习的是基于RSA算法的TLS握手,但是如今RSA 密钥交换算法的 TLS 握手过程,不仅慢,而且安全性也不高。

因此如果可以,尽量选用 ECDHE 密钥交换算法替换 RSA 算法,速度快,安全性也高。

6.3.2 升级TLS

如题,如果可以,直接把 TLS 1.2 升级成 TLS 1.3,TLS 1.3 大幅度简化了握手的步骤,完成 TLS 握手只要 1 RTT,而且安全性更高。

6.4 证书优化

为了验证的服务器的身份,服务器会在 TLS 握手过程中,把自己的证书发给客户端,以此证明自己身份是可信的。

6.4.1 证书传输

对于服务器的证书应该选择椭圆曲线(ECDSA)证书,而不是 RSA 证书,因为在相同安全强度下, ECC 密钥长度比 RSA 短的多。

6.4.2 证书验证

客户端在验证证书时,是个复杂的过程,会走证书链逐级验证,验证的过程不仅需要「用 CA 公钥解密证书」以及「用签名算法验证证书的完整性」,而且为了知道证书是否被 CA 吊销,客户端有时还会再去访问 CA, 下载 CRL 或者 OCSP 数据,以此确认证书的有效性。

现在基本都是使用使用OCSP(在线证书状态协议) 来查询证书的有效性,它的工作方式是向 CA 发送查询请求,让 CA 返回证书的有效状态。

6.5 会话复用

TLS 握手的目的就是为了协商出会话密钥,也就是对称加密密钥,那我们如果我们把首次 TLS 握手协商的对称加密密钥缓存起来待下次需要建立 HTTPS 连接时,直接「复用」这个密钥,不就减少 TLS 握手的性能损耗了吗?

下面的会话重用技术虽然好用,但是存在一定的安全风险,它们不仅不具备前向安全,而且有重放攻击的风险,所以应当对会话密钥设定一个合理的过期时间。

重放攻击:A给B发信息,被C窃听到了,然后AB通信完毕后C就可以冒充A给B发信息。

6.5.1 Session ID

Session ID 的工作原理是,客户端和服务器首次 TLS 握手连接后,双方会在内存缓存会话密钥,并用唯一的 Session ID 来标识。

当客户端再次连接时,hello 消息里会带上 Session ID,服务器收到后就会从内存找,如果找到就直接用该会话密钥恢复会话状态,跳过其余的过程,只用一个消息往返就可以建立安全通信。当然为了安全性,内存中的会话密钥会定期失效。

6.5.2 Session Ticket

Session ID具有两个缺点:

  • 服务器必须保持每一个客户端的会话密钥,随着客户端的增多,服务器的内存压力也会越大
  • 现在网站服务一般是由多台服务器通过负载均衡提供服务的,客户端再次连接不一定会命中上次访问过的服务器,于是还要走完整的 TLS 握手过程

为了解决 Session ID 的问题,就出现了 Session Ticket,服务器不再缓存每个客户端的会话密钥,而是把缓存的工作交给了客户端,类似于 HTTP 的 Cookie。

客户端与服务器首次建立连接时,服务器会加密「会话密钥」作为 Ticket 发给客户端,交给客户端缓存该 Ticket

客户端再次连接服务器时,客户端会发送 Ticket,服务器解密后就可以获取上一次的会话密钥,然后验证有效期,如果没问题,就可以恢复会话了,开始加密通信。

6.5.3 Pre-shared Key

前面的 Session ID 和 Session Ticket 方式都需要在 1 RTT 才能恢复会话。

而 TLS1.3 更为出色,对于重连 TLS1.3 只需要 0 RTT,原理和 Ticket 类似,只不过在重连时,客户端会把 Ticket 和 HTTP 请求一同发送给服务端,这种方式叫 Pre-shared Key。