计网学习笔记应用层篇3-HTTPS

计算机网络

Posted by Cc1over on June 11, 2019

计网学习笔记应用层篇3-HTTPS

前言

之前在写HTTP/2的时候,其实HTTP/2是的二进制分帧层就是建立在SSL\TSL上的,所以应用层篇的最后一篇笔记想写一写的就是HTTPS的学习

HTTPS

[Q1:为什么要引入HTTPS的机制?]

采取未加密的协议进行通信有如下弊端:

  • 通信使用明文,内容可能被窃听

  • 不验证通讯方的身份,可能遭遇伪装.(任何人都能发送请求,不管对方是谁都会返回响应)

  • 无法证明报文的完整性,可能会遭篡改.(没有办法确认发出的请求/响应和接收到的请求/响应前后一致)

[Q2:什么是HTTPS?]

  • HTTP+加密+认证+完整性保护 = HTTPS:HTTPS就是在HTTP上再加入加密处理和认证等机制
  • HTTPS是身披SSL保护外衣的HTTP: HTTPS并非应用层的一种新协议,只是HTTP通讯接口部分用SSL和TLS协议代替,所以HTTPS其实就是身披SSL保护外衣的HTTP

[Q3:HTTPS是如何实现加密的?]

记录下当时看这个知识的时候印象很深刻的程序员小灰漫画讲解:https://blog.csdn.net/bjweimengshu/article/details/87706654

SSL/TLS协议运行机制

和漫画中的流程一致:SSL/TLS协议的基本过程是:

  • 客户端向服务端索取并验证公钥
  • 双方协商生成对话秘钥
  • 双方采用对话秘钥进行加密通信

具体的握手阶段流程

  • 客户端发出请求(ClientHello)

    客户端向服务器发出加密通信的请求

    客户端向服务器提供的信息:

    • 支持的协议版本,比如TLS 1.0版
    • 一个客户端生成的随机数,稍后用于生成”对话密钥”
    • 支持的加密方法,比如RSA公钥加密
    • 支持的压缩方法
  • 服务器回应(SeverHello)

    服务器收到客户端请求后,向客户端发出回应

    回应信息:

    • 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信
    •  一个服务器生成的随机数,稍后用于生成”对话密钥”
    • 确认使用的加密方法,比如RSA公钥加密
    • 服务器证书
    • 需要确认客户端身份情况:会再包含一项请求,要求客户端提供”客户端证书”
  • 客户端回应

    客户端收到服务器回应以后,首先验证服务器证书。如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信

    如果证书没有问题,客户端就会从证书中取出服务器的公钥。然后,向服务器发送下面三项信息

    • 一个随机数。该随机数用服务器公钥加密,防止被窃听
    • 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送
    • 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验
  • 服务器最后回应

    • 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送
    • 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验

[Q:为什么需要3个随机数来生成一个对话秘钥?]

“不管是客户端还是服务器,都需要随机数,这样生成的密钥才不会每次都一样。由于SSL协议中证书是静态的,因此十分有必要引入一种随机因素来保证协商出来的密钥的随机性。

对于RSA密钥交换算法来说,pre-master-key本身就是一个随机数,再加上hello消息中的随机,三个随机数通过一个密钥导出器最终导出一个对称密钥。

pre master的存在在于SSL协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么pre master secret就有可能被猜出来,那么仅适用pre master secret作为密钥就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上pre master secret三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能完全不随机,可是是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的可不是一。”

[Q:Android如何实现HTTPS?]

优化演进

[Q:HTTPS的弊端?]

  • 2-RTT的延时:一次普通的HTTP请求,除了真实数据传输的耗时,实际上很多耗时存在于TCP连接的三次握手(1.5个RTT)的耗时上。而对于一次HTTPS的安全连接,则还需要花费时间在前期的会话密钥建立上,这里面存在1~2个RTT
  • 非对称加密CPU开销:非对称加密组件计算效率往往远低于对称加密组件,直接使用非对称加密组件加密业务数据,这样的性能损耗任何Server都是无法承受的

Session ID

Session ID是HTTPS加速的一种方式,TLS里提出的session cache机制,通过保存上一次握手后的会话状态,在下一次连接是继续复用上一次的握手结果,而无需进行新的握手流程

在HTTPS的握手过程中,服务器会为这一次连接生成一个会话ID(Session_id),同时端会为这个session_id保存相关的会话状态,比如协商好的会话密钥等

然后,服务器会把这个session_id回传给客户端,客户端收到后保存下来。在下一次建立Https连接时,直接把session_id传给服务器,服务器收到后会在本地查找之前保存的会话状态,如果找到,就直接回传给客户端,并发送握手结束事件。然后,双方就可以使用之前协商好的密钥直接开始通信了

不过,session_id保存session cache这种方式存在一个问题:如果同时有多台TLS服务器,而这个session cache默认只存在于最初协商的那台机器上,这就意味着没法在多台机器间共享

Session Ticket

Session ID存在的问题就是多台TLS服务器session_id无法共享,而解决的方案就是采用Session Ticket,这种方案的思路,就是将上面提到的session cache加密成一个Session Ticket,转存到客户端。下次建立连接时,客户端把Session Ticket带回给服务器,这个Ticket只有服务器能够解密,如果解密成功,说明Session未被篡改,那么就可以从中读取session信息并进行恢复,结束握手

这种方式就不存在多台服务器session共享的问题,另外,服务器也可以选择忽略这个Ticker,并启动一次完整的握手流程。

而且这个Session Ticket内部有一个缓存失效时间,如果客户端发现该Ticket已过期,则自动删除

感谢: