图解HTTP


图解HTTP

HTTP起源

HTTP最早由Tim Berners Lee提出用于知识共享的一种协议。因为在1989年之前,互联网只属于少数人。

最初的基本理念: 借助多文档之间的互相关联形成的超文本,连成可互相参阅的WWW(World Wide Web, 万维网)

构成WWW的三项基本技术: 1. 用于定义页面文本结构样式的标准通用标记语(Standard Generalized Markup Language)————HTML(HyperText Markup Language); 2. 用于传输的协议(HTTP); 3. 指定文档所在地址的URL(Uniform Resource Locator);

HTTP与Web发展的历史节点

  1. 1990年11月,欧洲核子研究中心(CERN)研发出世界上第一台Web服务器和Web浏览器;
  2. 1990,由于HTML1.0中存在大量模糊的部分,草案被直接放弃;
  3. 1993年,Mosaic问世(现代浏览器的祖先,由国家超级计算机中心[美国国家超级计算机应用中心]研制)
  4. 1994年,网景公司发布Netscape Navigator 1.0; 1995年,微软发布IE1.0, IE2.0,自此微软IE与网景浏览器爆发大战(具体细节:终于还是说再见!回忆那些年一起用过的IE)
  5. 1995年11月,HTML2.0诞生
  6. 2000年左右,网景浏览器败下阵来,自此IE一家独大
  7. 2004年,Mozilla基金会发布Firefox浏览器(与Netscape Navigator同宗),试图夺回失去的份额;
  8. 2008年,Google发布Chrome浏览器,半路杀进浏览器大战,也由于早期Chrome极致的运行速度和简洁时尚的界面,成功获得了市场认可;
  9. 2018年年底,微软宣布其最新版的Edge浏览器,将会采用Chromium内核;至此,基本形成Chrome浏览器一家独大的格局;

HTTP的几个版本

  1. HTTP/0.9:HTTP于1990年诞生,在被作为正式的标准确立前的HTTP,被统一称为HTTP/0.9;
  2. HTTP/1.0: HTTP 正式标准被确立是在1996年5月,并记载于RFC1945
  3. HTTP/1.1: 1997年1月公布,是目前(2019年3月)的主流版本;
    1. 1.1发布版RFC2068
    2. 1.1修订版RFC2616
  4. HTTP/2.0: 随着使用HTTP协议的场景越来越多,最初的关于HTTP的设想(主要用于文本传输)已经不能满足需求,因此HTTP/2.0诞生RFC7540

网络基础TCP/IP

首先说明,HTTP是在TCP/IP的基础上运行的。要理解这句话的含义,就要明白网络分层的概念。

  1. 应用层:定义用户提供通信服务时的活动;
  2. 传输层:定义通信服务中的数据传输机制;
  3. 网络层:定义通信服务中,数据传输的路径选择;
  4. 数据链路层: 定义通信服务中,链接网络的硬件部分的标准(例如操作系统,网络适配器NIC,光纤等物理部分);

TODO: 网络传输示意图

与HTTP关系密切的几个协议

  1. IP(Internet Protocol)协议, 位于网络层,用于定义数据传输路径。 在网络传输中,没有人能够掌握互联网中的传输局情况————这与路由选择这种机制有关;
  2. TCP协议:确保数据一定能够传输到目标地址。IP协议负责数据传输过程的路径选择,但是无法保证每次都能最终到达目标。TCP协议就是在IP协议的基础上,加了验证机制,如果无法收到目标机器确认收到数据的信号,则TCP协议会再一次发送传输失败的数据。
  3. DNS协议:DNS(Domain Name System)是用于解析域名与IP地址对应关系的服务。IP地址不方便人类记忆,但是域名可以;但计算机不理解域名,所以需要一个“翻译”角色,用于域名和IP地址的转换。

URI和URL

URI(Uniform Resource Identifier)中几个单词的含义。

Uniform: 统一的格式,用于将处理不同类型的资源; Resource: 可以被标识 的任何东西,资源也可以是多个资源的合体 Identifier: 资源标识符

RFC3986给出了URI 的几种格式

ftp://ftp.is.co.za/rfc/rfc1808.txt
http://www.ietf.org/rfc/rfc2396.txt
ldap://[2001:db8::7]/c=GB?objectClass?one
mailto:[email protected]
news:comp.infosystems.www.servers.unix
tel:+1-816-555-1212
telnet://192.0.2.16:80/
urn:oasis:names:specification:docbook:dtd:xml:4.1.2

URI的格式

  • 协议名:指定访问资源时使用的协议,也可以是data:javascript:等指定数据或脚本程序的方案名
  • 登录信息:(如果访问的资源需要验证信息)
  • 服务器地址:(必选)
  • 服务器端口号:(省略的情况下,使用默认端口号)
  • 带层次的文件路径:(必选)
  • 查询字符串:(用于传入参数)
  • 片段标识符:(用于标记已获取的资源中的子资源)

备注

并不是所有的HTTP协议都要符合RFC的标准,只要能在服务端和客户端进行正常通信,都可以作为一种协议,都可以在实际业务中使用。RFC的标准是一种规范,遵守规范的意义就在于能够符合大众标准,但不是唯一标准。

HTTPS

HTTP作为网络通信协议,实际上还有一些缺点:

  1. 明文传输方式,导致通信数据很容易被窃听;
  2. 无法验证通信对象的合法性;
  3. 无法保证通信数据的完整性;

明文传输

因为TCP/IP的工作机制,通信数据在互联网中传输是公开的,也就是说是可以被第三方看到的。单独这么看也许不存在问题,但如果传输数据是明文的方式,就不同了。这就好比你在广场上通过大声喊的方式与不远处的同伴说话。不仅你俩能听见彼此的沟通内容,广场上的其它人也能够知道。如果通过HTTP传输的信息是账户密码,信用卡号,那么你的这些敏感信息就会被泄露出去。

利用网络抓包或者嗅探器工具很容易抓取网络上的通信数据,常用的有wireshark

无法验证通信对象的合法性

服务端无法获取当前的请求就是来自于期望的客户端,而客户端也无法验证获取的响应数据来自真正的服务端。直白一点说,就是客户端和服务端无法验证自己到底是和谁在进行通信。

  • 客户端收到的响应可能来自于伪装的服务器;
  • 服务端收到的请求可能来自于伪装的客户端;
  • 服务端无法验证客户端是否具有访问特定自愿的权限(目前服务端可以验证客户端是否具有对应全向,但是仅通过HTTP协议本身无法做到这一点);

无法保证数据的完整性

使用HTTP进行通信,传输报文可以被第三方劫持然后修改后再进行传送,这就会发生数据被修改的情况。所以服务端和客户端收到的数据可能是被第三方修改过的数据但是却没有任何办法去验证是否被修改过。


针对HTTP存在的安全问题,产生了HTTPS (HTTP + 加密 + 认证 + 完整性保护 = HTTPS)。

HTTPS不是一种新的应用层协议,而是在HTTP协议的基础上,HTTP通信接口采用SSL(Secure Socket Layer)和 TSL(Transport Layer Security)。

SSL采用的加密方式: 存在加密算法和加密密钥。 加密算法公开,加密密钥私有。没有对应的密钥,无法解开对应的加密数据。

加密传输

使用HTTPS,传输的数据会在加密后进行传输(通过HTTP)。这样,即使数据被第三方截获,如果没有正确的解密密钥依然无法获取通信内容。所以说,只要通信双发约定好密钥,就可以进行安全通信。

But,在约定密钥前需要服务端和客户端进行协商,这时候密钥还未加密,通信过程依然是不安全的。如果被第三方获知了密钥,则通信内容依然不安全。

非对称加密

什么是非对称加密? 密钥分为公钥和私钥。私钥有服务端保存,公钥可以分发给客户端。客户端只管发送加密后的内容,这样即使数据被第三方截获,因为没有对应的私钥,所以也无法解析加密数据。

中间人攻击

非对称加密解决了加密密钥私有的问题,但是如何保证客户端接收到公钥就是服务端分发的公钥呢,也许数据早已被第三方截获,然后第三方再生成一个新的公钥钥给客户端。这样,客户端加密后数据也能被第三方解析出来(因为公钥是第三方生成的)。然后第三方修改通信数据后,在利用真正的公钥与服务端进行通信。这样就会导致客户端和服务端之间有一个“中间人”。

所以,只要保证自己的公钥能够被安全地发放给客户端,就能保证通信的安全性。

找一个可信的第三方

服务端把自己的公钥托管给可信的第三方,第三方会保存服务端的公钥并生成数字证书。客户端利用第三方认证机构的公钥对颁发的证书进行验证,验证证书中公钥的有效性。而如何保证第三方认证结构的公钥的有效性呢?方案很简单,内置在浏览器中。浏览器厂商会将信任的第三方认证机构的公钥预先植入在浏览器中。这样的话,就能保证整个过程通信过程都是安全有效的。

EV SSL证书

证书除了可以验证公钥的有效性,还可以用来验证对应的服务的企业组织的真实性(是否真实存在,是否合法等)。这样的证书就称为Extended Validation SSL Certificate。

HTTPS 带来性能开销

使用HTTPS进行通信,不可避免地要产生额外的性能开销。这主要是两个方面

  • 加密/解密带来的 CPU/内存之类的计算性能开销;
  • HTTPS会产生更多的通信过程,带来额外的网络开销;

并不是所有的通信都应该使用HTTPS

在当前环境下,HTTPS除了会产生额外的性能开销,还存在证书费用问题。从项目工程的角度出发,为节省资源,我们可以只在特定节点和过程采用HTTPS(比如账户登录,支付等)。而内容分发等不存在认证的过程,可以采用HTTP。

确认用户身份的认证

何为认证? 核对“只有登录者本人才知道的信息”或者“只有登录者本人才会有的信息”。

一般情况下,有下面几种类型的 信息可用于认证:

  1. 密码:用户本人才知道的字符串;
  2. 动态令牌:仅限用户本人持有的设备生成的一次性密码;
  3. 数字证书:仅限用户本人(终端)持有的数字签名;
  4. 生物认证:指纹、虹膜和面部特征等用户本人的生物信息;
  5. IC卡等:仅限用户本人持有的信息;

HTTP中的认证方式:

  1. BASIC认证
  2. DIGEST认证
  3. SSL客户端认证
  4. 基于表单认证