Http和Https网络协议

HTTP和HTTPS发展历史

什么是HTTP?

超文本传输协议(英语:HyperText Transfer Protocol,缩写:HTTP),是一个基于请求与响应,无状态的,应用层的协议,常基于TCP/IP协议传输数据,互联网上应用最为广泛的一种网络协议,所有的WWW文件都必须遵守这个标准。设计HTTP的初衷是为了提供一种发布和接收HTML页面的方法。

  • 发展历史:
版本 产生时间 内容 发展现状
HTTP/0.9 1991年 不涉及数据包传输,规定客户端和服务器之间通信格式,只能GET请求 没有作为正式的标准
HTTP/1.0 1996年 传输内容格式不限制,增加PUT、PATCH、HEAD、 OPTIONS、DELETE命令 正式作为标准
HTTP/1.1 1997年 持久连接(长连接)、节约带宽、HOST域、管道机制、分块传输编码 2015年前使用最广泛
HTTP/2.0 2015年 多路复用、服务器推送、头信息压缩、二进制协议等 逐渐覆盖市场

使用HTTP/1.1和HTTP/2同时请求379张图片,观察请求的时间,明显看出HTTP/2性能占优势

多路复用:通过单一的HTTP/2连接请求发起多重的请求-响应消息,多个请求stream共享一个TCP连接,实现多留并行而不是依赖建立多个TCP连接。

HTTP报文格式

http报文格式

一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成

1
2
3
4
5
6
7
<request-line>

<headers>

<blank line>

[<request-body>]

HTTP响应也由三个部分组成,分别是:状态行、消息报头、响应正文

1
2
3
4
5
6
7
<status-line>

<headers>

<blank line>

[<response-body>]
常见状态码

常见状态代码、状态描述的说明如下。

  • 200 OK:客户端请求成功。

  • 400 Bad Request:客户端请求有语法错误,不能被服务器所理解。

  • 401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。

  • 403 Forbidden:服务器收到请求,但是拒绝提供服务。

  • 404 Not Found:请求资源不存在,举个例子:输入了错误的URL。

  • 500 Internal Server Error:服务器发生不可预期的错误。

  • 503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。

  • 1xx:指示信息–表示请求已接收,继续处理。

  • 2xx:成功–表示请求已被成功接收、理解、接受。

  • 3xx:重定向–要完成请求必须进行更进一步的操作。

  • 4xx:客户端错误–请求有语法错误或请求无法实现。

  • 5xx:服务器端错误–服务器未能实现合法的请求。

什么是HTTPS?

HTTPS是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立全信道,加密数据包。HTTPS使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私完整性

PS:TLS是传输层加密协议,前身是SSL协议,由网景公司1995年发布,有时候两者不区分。

HTTP VS HTTPS

HTTP特点:

  • 无状态:协议对客户端没有状态存储,对事物处理没有“记忆”能力,比如访问一个网站需要反复进行登录操作
  • 无连接:HTTP/1.1之前,由于无状态特点,每次请求需要通过TCP三次握手四次挥手,和服务器重新建立连接。比如某个客户机在短时间多次请求同一个资源,服务器并不能区别是否已经响应过用户的请求,所以每次需要重新响应请求,需要耗费不必要的时间和流量。
  • 基于请求和响应:基本的特性,由客户端发起请求,服务端响应
  • 简单快速、灵活
  • 通信使用明文、请求和响应不会对通信方进行确认、无法保护数据的完整性

针对无状态的一些解决策略:
场景:逛电商商场用户需要使用的时间比较长,需要对用户一段时间的HTTP通信状态进行保存,比如执行一次登陆操作,在30分钟内所有的请求都不需要再次登陆。

  1. 通过Cookie/Session技术
  2. HTTP/1.1持久连接(HTTP keep-alive)方法,只要任意一端没有明确提出断开连接,则保持TCP连接状态,在请求首部字段中的Connection: keep-alive即为表明使用了持久连接

HTTPS特点:

  • 基于HTTP协议,通过SSL或TLS提供加密处理数据、验证对方身份以及数据完整性保护
    • 内容加密:采用混合加密技术,中间者无法直接查看明文内容
    • 验证身份:通过证书认证客户端访问的是自己的服务器
    • 保护数据完整性:防止传输的内容被中间人冒充或者篡改

混合加密:结合非对称加密和对称加密技术。客户端使用对称加密生成密钥对传输数据进行加密,然后使用非对称加密的公钥再对秘钥进行加密,所以网络上传输的数据是被秘钥加密的密文和用公钥加密后的秘密秘钥,因此即使被黑客截取,由于没有私钥,无法获取到加密明文的秘钥,便无法获取到明文数据。

.数字摘要:通过单向hash函数对原文进行哈希,将需加密的明文“摘要”成一串固定长度(如128bit)的密文,不同的明文摘要成的密文其结果总是不相同,同样的明文其摘要必定一致,并且即使知道了摘要也不能反推出明文。

数字签名技术:数字签名建立在公钥加密体制基础上,是公钥加密技术的另一类应用。它把公钥加密技术和数字摘要结合起来,形成了实用的数字签名技术。

  • 收方能够证实发送方的真实身份;
  • 发送方事后不能否认所发送过的报文;
  • 收方或非法者不能伪造、篡改报文。

https加密过程

非对称加密过程需要用到公钥进行加密,那么公钥从何而来?其实公钥就被包含在数字证书中,数字证书通常来说是由受信任的数字证书颁发机构CA,在验证服务器身份后颁发,证书中包含了一个密钥对(公钥和私钥)和所有者识别信息。数字证书被放到服务端,具有服务器身份验证和数据传输加密功能。

HTTP通信传输

客户端输入URL回车,DNS解析域名得到服务器的IP地址,服务器在80端口监听客户端请求,端口通过TCP/IP协议(可以通过Socket实现)建立连接。HTTP属于TCP/IP模型中的应用层协议。

报文从应用层传送到运输层,运输层通过TCP三次握手和服务器建立连接,四次挥手释放连接。

tcp传输层三次握手

tcp传输层三次握手

Q1: 为什么需要三次握手呢?为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

  • 比如:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段,但是server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求,于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了,由于client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据,但server却以为新的运输连接已经建立,并一直等待client发来数据。所以没有采用“三次握手”,这种情况下server的很多资源就白白浪费掉了。

tcp传输层四次挥手

tcp传输层四次挥手

Q2:为什么需要四次挥手呢?

  • TCP是全双工模式,当client发出FIN报文段时,只是表示client已经没有数据要发送了,client告诉server,它的数据已经全部发送完毕了;但是,这个时候client还是可以接受来server的数据;当server返回ACK报文段时,表示它已经知道client没有数据发送了,但是server还是可以发送数据到client的;
  • 当server也发送了FIN报文段时,这个时候就表示server也没有数据要发送了,就会告诉client,我也没有数据要发送了,如果收到client确认报文段,之后彼此就会愉快的中断这次TCP连接。

Q3:当客户端进入TIME-WAIT状态的时候(也就是第四次挥手的时候),必须经过时间计数器设置的时间2MSL(最长报文段寿命)后,才能进入关闭状态,这时为什么呢?

  • 为了保证客户端发送的最后一个ACK报文段能够到达服务器。因为这个ACK有可能丢失,从而导致处在LAST-ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK,接着客户端再重传一次确认,重新启动时间等待计时器。最后客户端和服务器都能正常的关闭。假设客户端不等待2MSL,而是在发送完ACK之后直接释放关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态。

  • 还可以防止已失效的报文段。客户端在发送最后一个ACK之后,再经过经过2MSL,就可以使本链接持续时间内所产生的所有报文段都从网络中消失。从保证在关闭连接后不会有还在网络中滞留的报文段去骚扰服务器。

注意:在服务器发送了FIN-ACK之后,会立即启动超时重传计时器。客户端在发送最后一个ACK之后会立即启动时间等待计时器。

HTTPS实现原理

https = http + tls / ssl

https握手过程

SSL建立连接过程

  • 在通信双方建立可靠的 TCP 连接之后,我们就需要通过 TLS 握手交换双方的密钥了

https握手过程

  1. 客户端向服务端发送 Client Hello 消息,其中携带客户端支持的协议版本、加密算法、压缩算法以及客户端生成的随机数
  2. 服务端收到客户端支持的协议版本、加密算法等信息后;
    1. 向客户端发送 Server Hello 消息,并携带选择特定的协议版本、加密方法、会话 ID 以及服务端生成的随机数
    2. 向客户端发送 Certificate 消息,即服务端的证书链,其中包含证书支持的域名、发行方和有效期等信息;
    3. 向客户端发送 Server Key Exchange 消息,传递公钥以及签名等信息;
    4. 向客户端发送可选的消息 CertificateRequest,验证客户端的证书;
    5. 向客户端发送 Server Hello Done 消息,通知服务端已经发送了全部的相关信息;
  3. 客户端收到服务端的协议版本、加密方法、会话 ID 以及证书等信息后,验证服务端的证书;
    1. 向服务端发送 Client Key Exchange 消息,包含使用服务端公钥加密后的随机字符串,即预主密钥(Pre Master Secret);
    2. 向服务端发送 Change Cipher Spec 消息,通知服务端后面的数据段会加密传输;
    3. 向服务端发送 Finished 消息,其中包含加密后的握手信息;
  4. 服务端收到 Change Cipher Spec 和 Finished 消息后;
    1. 向客户端发送 Change Cipher Spec 消息,通知客户端后面的数据段会加密传输;
    2. 向客户端发送 Finished 消息,验证客户端的 Finished 消息并完成 TLS 握手;

TLS 握手的关键在于利用通信双方生成的随机字符串和服务端的公钥生成一个双方经过协商后的密钥,通信的双方可以使用这个对称的密钥加密消息防止中间人的监听和攻击,保证通信的安全。

https握手过程

  1. client向server发送请求https://baidu.com,然后连接到server的**443**端口,发送的信息主要是**随机值1**和**客户端支持的加密算法**。
  2. server接收到信息之后给予client响应握手信息,包括随机值2匹配好的协商加密算法,这个加密算法一定是client发送给server加密算法的子集。
  3. 随即server给client发送第二个响应报文是数字证书。服务端必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面,这套证书其实就是一对公钥和私钥。传送证书,这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间、服务端的公钥,第三方证书认证机构(CA)的签名,服务端的域名信息等内容
  4. 客户端解析证书,这部分工作是由客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随即值(预主秘钥)
  5. 客户端认证证书通过之后,接下来是通过随机值1、随机值2和预主秘钥组装会话秘钥。然后通过证书的公钥加密会话秘钥
  6. 传送加密信息,这部分传送的是用证书加密后的会话秘钥,目的就是让服务端使用秘钥解密得到随机值1、随机值2和预主秘钥
  7. 服务端解密得到随机值1、随机值2和预主秘钥,然后组装会话秘钥,跟客户端会话秘钥相同。
  8. 客户端通过会话秘钥加密一条消息发送给服务端,主要验证服务端是否正常接受客户端加密的消息。
  9. 同样服务端也会通过会话秘钥加密一条消息回传给客户端,如果客户端能够正常接受的话表明SSL层连接建立完成了。

Q4:怎么保证保证服务器给客户端下发的公钥是真正的公钥,而不是中间人伪造的公钥呢?

  • https握手过程

https握手过程

  • 数字证书内容
    • 包括了加密后服务器的公钥、权威机构的信息、服务器域名,还有经过CA私钥签名之后的证书内容(经过先通过Hash函数计算得到证书数字摘要,然后用权威机构私钥加密数字摘要得到数字签名),签名计算方法以及证书对应的域名
  • 验证证书安全性过程
    • 当客户端收到这个证书之后,使用本地配置的权威机构的公钥对证书进行解密得到服务端的公钥和证书的数字签名,数字签名经过CA公钥解密得到证书信息摘要。
    • 然后用证书签名的方法计算一下当前证书的信息摘要,与收到的信息摘要作对比,如果一样,表示证书一定是服务器下发的,没有被中间人篡改过。因为中间人虽然有权威机构的公钥,能够解析证书内容并篡改,但是篡改完成之后中间人需要将证书重新加密,但是中间人没有权威机构的私钥,无法加密,强行加密只会导致客户端无法解密,如果中间人强行乱修改证书,就会导致证书内容和证书签名不匹配。
  • 那第三方攻击者能否让自己的证书显示出来的信息也是服务端呢?
    • (伪装服务端一样的配置)显然这个是不行的,因为当第三方攻击者去CA那边寻求认证的时候CA会要求其提供例如域名的whois信息、域名管理邮箱等证明你是服务端域名的拥有者,而第三方攻击者是无法提供这些信息所以他就是无法骗CA他拥有属于服务端的域名。

Q5:中间人有可能篡改证书吗?

  • 假如中间人获取到了CA证书,并修改了证书中的域名,但是此时它没有CA机构的私钥,所以它无法得到一个新的签名,然后客户端收到该篡改的证书后,通过私钥解密出来一个原证书信息的摘要,并且客户端对收到的证书内容生成信息摘要,发现两个信息不一致,就会终止通信,防止信息泄露。

Q6:HTTPS必须在每次请求中都要先在SSL/TLS层进行握手传输密钥吗?

  • 其实是通过一个Session Identifier(会话标识符),该Session ID是 TLS 握手中生成的 Session ID。服务端可以将 Session ID 协商后的信息存起来,浏览器也可以保存 Session ID,并在后续的 Client Hello 握手中带上它,如果服务端能找到与之匹配的信息,就可以完成一次快速握手。

优缺点

  • 安全性考虑:
    .
    • HTTPS协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用
    • SSL证书的信用链体系并不安全,特别是在某些国家可以控制CA根证书的情况下,中间人攻击一样可行
  • 成本考虑:
    • SSL证书需要购买申请,功能越强大的证书费用越高
    • SSL证书通常需要绑定IP,不能在同一IP上绑定多个域名,IPv4资源不可能支撑这个消耗(SSL有扩展可以部分解决这个问题,但是比较麻烦,而且要求浏览器、操作系统支持,Windows XP就不支持这个扩展,考虑到XP的装机量,这个特性几乎没用)。
    • 根据ACM CoNEXT数据显示,使用HTTPS协议会使页面的加载时间延长近50%,增加10%到20%的耗电。
    • HTTPS连接缓存不如HTTP高效,流量成本高。
    • HTTPS连接服务器端资源占用高很多,支持访客多的网站需要投入更大的成本。
    • HTTPS协议握手阶段比较费时,对网站的响应速度有影响,影响用户体验。比较好的方式是采用分而治之,类似12306网站的主页使用HTTP协议,有关于用户信息等方面使用HTTPS。

参考:

为什么 HTTPS 需要 7 次握手以及 9 倍时延

HTTP和HTTPS协议,看一篇就够了

0%