HTTPs协议

Posted by Mars . Modified at

HTTPS协议内容、TLS握手过程

  1. HTTP协议的缺点

  2. HTTPs协议

一、HTTPs协议

1. HTTP协议的缺点

  1. 通信不加密,使用明文传输;
  2. 不验证通信双方的身份,有可能遭遇伪装;
  3. 无法验证报文的完整性,可能遭到篡改。

2. HTTPs协议

HTTPs协议在HTTP协议基础上,在运输层(TCP)与应用层(HTTP)之间,添加一层安全层,使用SSL/TLS协议对http报文进行加密处理,实现双方安全通信。

所以HTTPs也叫HTTP-over-ssl/tls。

HTTPs = HTTP + 加密 + 身份认证 + 完整性保护

2.1 加密方式:对称与非对称加密

现代加密方式中,算法是公开的,而解密需要的密钥是保密的。

对称加密:客户端与服务器都使用同一个密钥进行加密、解密。(双方共同依赖密钥的相互通信是个问题,也就是密钥本身该如何加密传输)

非对称加密:密钥分为公钥和私钥,公钥是公开的密钥,私钥是保密的密钥。一段用公钥加密的密文只能用私钥解密,而用私钥加密的密文只能用公钥解密。(解决了对称加密密钥无法相互传输的问题,一方用公钥加密,另一方接收后用本地私钥解密即可,无需传递私钥。缺点是效率较低)

2.2 HTTPs的加密方式

混合加密: 先使用非对称加密传递密钥,然后利用对称加密传输信息。

HTTPs中使用的TLS协议,一共涉及三种加密(算法)技术:① 用于传递会话对称密钥的非对称加密算法(DH算法、RSA算法等);② 用于会话的对称加密算法(DES、3DES、AES); ③ 用于校验数据完整性的摘要算法(MD5、SHA1、SHA256等)。

2.3 数字证书:公钥的真实性问题

通信对象的公钥如何确认其真实性,而不是中间者伪造?

解决方式是:选取值得信任的第三方认证机构,对公钥进行认证,并提供数字签名用于校验公钥的真实性。 内部机制如下:

  1. 服务器方向第三方认证机构CA(Certificate Authority)(比如VeriSign威立信)提交认证申请,并提供公钥;
  2. VeriSign对服务器方进行审查,确认真实性后发放证书,其中包含公钥和VeriSign使用自己内部私钥生成的数字签名;

    数字签名是怎么生成的?

    1. CA对服务器方进行审查后,生成一份证书明文数据initData,包括服务器公钥、Hash算法、证书过期时间、持有者信息等。
    2. 使用Hash算法对initData进行Hash处理,得到一份数据摘要initAbstract;
    3. 使用CA私钥对initAbstract进行加密,得到数字签名Sign;
    4. 组合证书明文数据initData和数字签名Sign,形成证书。
  3. 服务器将这个证书发送给客户端;
  4. VeriSign的公钥(和其他一些常见认证机构的公钥)已经内置在客户端浏览器中,客户端可以利用这个公钥,对证书的数字签名进行解密,确认服务器公开密钥的真实性(身份确认);

    如何确认证书内容没有遭到篡改?

    1. 客户端使用Hash算法对证书明文数据initData进行Hash化处理,得到数据摘要abstract;
    2. 客户端使用浏览器内置CA公钥,对数字签名进行解密,得到原始数据摘要initAbstract;
    3. 按理说,这两份摘要(initAbstract和abstract)应该是相同的,如果不同则证明中间有人修改过证书,证书不值得信任。(中间人不可能通过同时修改数字签名达到二者一致,因为中间人没有CA私钥)
  5. 客户端此时就可以信任地使用服务器公钥加密报文,进行信息传递了。

2.4 HTTPs的通信过程

HTTPs先进行TCP握手,然后进行TLS握手,然后进行加密的HTTP通信。

TLS通信整体分为三个步骤:

① 验证服务器端身份,获取服务器端公钥; ② 双方协商生成对话密钥; ③ 使用对话密钥进行对称加密通信。

其中前两步是TLS握手阶段,这个阶段的所有报文都是明文。TLS1.2握手的流程如下:

TLS1.3的握手有少许差别,但是原理是一样的。

  1. 客户端发出ClientHello请求,内容包含:一个客户端生成的随机数rand1、支持的TLS协议版本、支持的加密算法、支持的压缩方法;
  2. 服务器端回应ServerHello报文,内容包含:一个服务器端生成的随机数rand2、确认的TLS协议版本、加密算法和压缩方法;
  3. 服务端发送服务器证书(公钥和第三方机构数字签名)
  4. 客户端收到服务器证书后,对签名进行验证确认服务器身份,如果身份可疑,发出警告提示并由用户确定是否继续通信;
  5. 客户端确认服务器身份OK后,取出服务器公钥,然后生成一个随机数pre-master key,并使用服务器公钥对rand1、rand2和pre-master key三者的组合数进行加密,生成双方对话密钥
  6. 客户端向服务器发送报文,内容包含:生成的对话密钥、编码改变通知、客户端握手结束通知;
  7. 第一次使用对话密钥的加密通信:客户端发送前面已发送全部内容的一个Hash值,用来供服务器校验(通信数据完整性);
  8. 服务器收到后,用私钥解密出对话密 钥,向客户端发送确认报文:session ticket(如果支持),编码改变通知、服务器握手结束通知;
  9. 服务器发送前面全部内容的Hash值,用来供客户端校验(通信数据完整性);
  10. 从此之后,双方使用同一个对话密钥,加密报文内容,进行常规的Http加密通信。

Ping douban.com 握手抓包WireShark

Https握手抓包

2.5 HTTPs的缺点?为什么不一直使用?

  • HTTPs的加解密过程繁琐,消耗了两端CPU和内存资源,速度更慢(相比于HTTP慢2~100倍),一般只用在敏感数据的传输上;
  • HTTPs通信中需要用到数字签名证书,服务器端必须向权威机构购买,是一笔额外的开销。

2.6 Https的会话复用

  • Https的非对称加密握手过程,耗时长,计算量大,非常消耗双方资源;
  • 会话复用的实现,解决了这个问题;
  • Https会话复用的两种机制:
    1. session ID: 服务器存储主要会话信息;
      • session ID由客户端发起,在client hello报文中发送;
      • 服务端根据session ID进行匹配,找到之前的某次会话信息,如果成功匹配会在server hello报文中携带这个session id;
      • 双方绕过了密钥协商过程,直接复用之前的会话密钥;
    2. session ticket:客户端存储主要会话信息。
      • session ticket由服务端生成,它只有用服务端自己的私钥才能解密;
      • session ticket在双方第一次加密握手结束之后,发送给客户端,由客户端保存;
      • 客户端下次再和服务端进行连接的时候,client hello报文携带这个session ticket,服务端可以对它进行解密,拿出里面的会话密钥直接复用,双方因此绕过了复杂的加密流程。
  • 在session ID机制和session ticket机制同时存在的情况下,session ticket生效,优先级更高
  • session ID模式和session ticket模式的区别是:
    • session ID:
      • session ID由客户端生成,服务端需要保存id和对应会话状态的一个字典,增大了服务端压力;
      • session ID在服务器集群中使用,因为两次访问可能对应不同的响应服务器,因此sesision ID复用率下降,需要用公共储存介质来实现复用;
    • session ticket:
      • session ticket由服务端用自己的密钥ticket-key生成,里面携带了会话的密钥等信息,且只有服务端才能解密;
      • session ticket由客户端保存,服务端不用保存,减小了服务端压力;
      • 对于服务器集群,所有服务器都必须使用同一个密钥ticket-key,时间久了会不安全,一般需要定时轮换;
Keywords: Network
previousPost nextPost
已经有 1000000 个小伙伴看完了这篇推文。