计算机网络之HTTP/HTTPS/Cookie/Session/DNS协议

759 阅读39分钟

网络模型

随着技术的发展,计算机的应用越来越广泛,计算机之间的通信开始了百花齐放的状态,每个具有独立计算服务体系的信息技术公司都会建立自己的计算机通信规则,而这种情况会导致异构计算机之间无法通信,极大的阻碍了网络通信的发展,至此为了解决这个问题,国际标准化组织(ISO)制定了 OSI 模型,该模型定义了不同计算机互联的标准,OSI 模型把网络通信的工作分为 7 层,分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层

这七层模型是设计层面的概念,每一层都有固定要完成的职责和功能,分层的好处在于清晰和功能独立性,但分层过多会使层次变的更加复杂,虽然不需要实现本层的功能,但是也需要构造本层的上下文,空耗系统资源,所以在落地实施网络通信模型的时候将这七层模型简化合并为四层模型分别是应用层、传输层、网络层、网络接口层(各层之间的模型、协议统称为:TCP/IP协议簇)。

image-20210415202829666.png 从上图可以看到,TCP/IP模型合并了OSI模型的应用层、表示层和会话层,将OSI模型的数据链路层和物理层合并为网络访问层。

上图还列出了各层模型对应TCP/IP协议栈中的协议以及各层协议之间的关系。比如DNS协议是建立在TCP和UDP协议的基础上,FTP、HTTP、TELNET协议建立在TCP协议的基础上,NTP、TFTP、SNMP建立在UDP协议的基础上,而TCP、UDP协议又建立在IP协议的基础上,以此类推….

OSI中的层功能TCP/IP协议族
应用层文件传输,电子邮件,文件服务,虚拟终端TFTP,HTTP,SNMP,FTP,SMTP,DNS,RIP,Telnet
表示层数据格式化,代码转换,数据加密
会话层控制应用程序之间会话能力;如不同软件数据分发给不同软件ASAP、TLS、SSH、ISO 8327 / CCITT X.225、RPC、NetBIOS、ASP、Winsock、BSD sockets
传输层端到端传输数据的基本功能TCP、UDP
网络层定义IP编址,定义路由功能;如不同设备的数据转发IP,ICMP,RIP,OSPF,BGP,IGMP
数据链路层定义数据的基本格式,如何传输,如何标识SLIP,CSLIP,PPP,ARP,RARP,MTU
物理层二进制数据形式在物理媒体上传输数据ISO2110,IEEE802

当我们某一个网站上不去的时候。通常会 ping 一下这个网站

ping 可以说是 ICMP 的最著名的应用,是 TCP/IP 协议的一部分。利用ping命令可以检查网络是否连通,可以很好地帮助我们分析和判定网络故障。

HTTP协议

URI 和 URL

每个Web 服务器资源都有一个名字,这样客户端就可以说明他们感兴趣的资源是什么了,服务器资源名被称为统一资源标识符(Uniform Resource Identifier,URI)。URI 就像因特网上的邮政地址一样,在世界范围内唯一标识并定位信息资源。

统一资源定位符(URL)是资源标识符最常见的形式。 URL 描述了一台特定服务器上某资源的特定位置。

现在几乎所有的 URI 都是 URL。

URI 的第二种形式就是统一资源名(URN)。URN 是作为特定内容的唯一名称使用的,与目前的资源所在地无关。

HTTP消息的结构

事务和报文

客户端是怎样通过 HTTP 与 Web 服务器及其资源进行事务处理的呢?一个 HTTP 事务由一条请求命令(从客户端发往服务器)和一个响应(从服务器发回客户端)结果组成。这种通信是通过名为HTTP报文(HTTP Message)的格式化数据块进行的。

HTTP事务

image-20210416092701404.png

image-20210204215121454-1623210718059.png

报文

HTTP 报文是纯文本,不是二进制代码。从 Web 客户端发往 Web 服务器的 HTTP 报文称为请求报文(request message)。从服务器发往客户端的报文称为响应报文。

image-20210416092722655.png HTTP 报文包括三部分:

  • 起始行
  • 首部字段
  • 主体

常见HTTP 首部字段

a、通用首部字段(请求报文与响应报文都会使用的首部字段)

​ 既可以出现在请求报文中,也可以出现在响应报文中。

  • Date:创建报文时间
  • Connection:连接的管理
  • Cache-Control:缓存的控制
  • Transfer-Encoding:报文主体的传输编码方式

b、请求首部字段(请求报文会使用的首部字段)

​ 从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。

  • Host:请求资源所在服务器
  • Accept:可处理的媒体类型
  • Accept-Charset:可接收的字符集
  • Accept-Encoding:可接受的内容编码
  • Accept-Language:可接受的自然语言

**c、响应首部字段(**响应报文会使用的首部字段)

​ 从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。

  • Accept-Ranges:可接受的字节范围
  • Location:令客户端重新定向到的URI
  • Server:HTTP服务器的安装信息

d、实体首部字段(请求报文与响应报文的的实体部分使用的首部字段)

​ 针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更 新时间等与实体有关的信息。

  • Allow:资源可支持的HTTP方法
  • Content-Type:实体主类的类型
  • Content-Encoding:实体主体适用的编码方式
  • Content-Language:实体主体的自然语言
  • Content-Length:实体主体的的字节数
  • Content-Range:实体主体的位置范围,一般用于发出部分请求时使用

方法

Http 协议定义了很多与服务器交互的方法,最基本的有 4 种,分别是 GET,POST,PUT,DELETE. 一个 URL 地址用于描述一个网络上的资源,而HTTP中的GET, POST, PUT, DELETE就对应着对这个资源的查,改,增,删4个操作。 我们最常见的就是 GET 和 POST 了。GET 一般用于获取/查询资源信息,而 POST 一般用于更新资源信息。

GET、HEAD、PUT、POST、TRACE、OPTIONS、DELETE

image-20210609115818731.png

GET与POST的区别

GET与POST是我们常用的两种HTTP Method,二者之间的区别主要包括如下五个方面:

  1. 从功能上讲,GET一般用来从服务器上获取资源,POST一般用来更新服务器上的资源;
  2. 从REST服务角度上说,GET是幂等的,即读取同一个资源,总是得到相同的数据,而POST不是幂等的,因为每次请求对资源的改变并不是相同的;进一步地,GET不会改变服务器上的资源,而POST会对服务器资源进行改变;
  3. 从请求参数形式上看,GET请求的数据会附在URL之后,即将请求数据放置在HTTP报文的 请求头 中,以?分割URL和传输数据,参数之间以&相连。特别地,如果数据是英文字母/数字,原样发送;否则,会将其编码为 application/x-www-form-urlencoded MIME 字符串(如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII);而POST请求会把提交的数据则放置在是HTTP请求报文的 请求体 中。
  4. 就安全性而言,POST的安全性要比GET的安全性高,因为GET请求提交的数据将明文出现在URL上,而且POST请求参数则被包装到请求体中,相对更安全。
  5. 从请求的大小看,GET请求的长度受限于浏览器或服务器对URL长度的限制,允许发送的数据量比较小,而POST请求则是没有大小限制的。

HTTP请求结构: 请求方式 + 请求URI + 协议及其版本

HTTP响应结构: 状态码 + 原因短语 + 协议及其版本

状态码

每条HTTP响应报文返回时都会携带一个状态码。状态码是一个三位数字的代码,告知客户端请求是否成功,或者是都需要采取其他动作。

  • 1xx:表明服务端接收了客户端请求,客户端继续发送请求;
  • 2xx:客户端发送的请求被服务端成功接收并成功进行了处理;
  • 3xx:服务端给客户端返回用于重定向的信息;
  • 4xx:客户端的请求有非法内容;
  • 5xx:服务端未能正常处理客户端的请求而出现意外错误。

image-20210609120042499.png

  • 200 OK:表示从客户端发送给服务器的请求被正常处理并返回;
  • 204 No Content:表示客户端发送给客户端的请求得到了成功处理,但在返回的响应报文中不含实体的主体部分(没有资源可以返回)
  • 206 Patial Content:表示客户端进行了范围请求,并且服务器成功执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容。
  • 301 Moved Permanently永久性重定向,表示请求的资源被分配了新的URL,之后应使用更改的URL;
  • 302 Found临时性重定向,表示请求的资源被分配了新的URL,希望本次访问使用新的URL;
  • 303 See Other:表示请求的资源被分配了新的URL,应使用GET方法定向获取请求的资源
  • 304 Not Modified:表示客户端发送附带条件(是指采用GET方法的请求报文中包含if-Match、If-Modified-Since、If-None-Match、If-Range、If-Unmodified-Since中任一首部)的请求时,服务器端允许访问资源,但是请求为满足条件的情况下返回改状态码;
  • 400 Bad Request:表示请求报文中存在语法错误;
  • 401 Unauthorized:未经许可,需要通过HTTP认证;
  • 403 Forbidden:服务器拒绝该次访问(访问权限出现问题)
  • 404 Not Found:表示服务器上无法找到请求的资源,除此之外,也可以在服务器拒绝请求但不想给拒绝原因时使用;
  • 500 Inter Server Error:表示服务器在执行请求时发生了错误,也有可能是web应用存在的bug或某些临时的错误时;
  • 503 Server Unavailable:表示服务器暂时处于超负载或正在进行停机维护,无法处理请求;

HTTP 是个应用层协议。HTTP 无需操心网络通信的具体细节,而是把这些细节都交给了通用可靠的因特网传输协议 TCP/IP。

在 HTTP 客户端向服务器发送报文之前,需要用网络协议(Internet Protocol,IP)地址和端口号在客户端和服务器之间建立一条 TCP/IP 协议。而 IP 地址就是通过 URL 提供的,像 http://207.200.21.11:80/index.html,还有使用域名服务(Domain Name Services,DNS)的 http://www.lazyegg.net

image-20210416092833948.png 浏览器是怎样通过 HTTP 显示位于远端服务器中的某个简单 HTML资源的:

  • 浏览器从 URL 中解析出服务器的主机名;
  • 浏览器将服务器的主机名转换成服务器的 IP 地址;
  • 浏览器将端口号(如果有的话)从URL中解析出来;
  • 浏览器建立一条与 Web 服务器的 TCP 连接;
  • 浏览器向服务器发送一条 HTTP 请求报文;
  • 服务器向浏览器回送一条 HTTP 响应报文;
  • 关闭连接,浏览器显示文档

协议版本

  • HTTP/0.9

    HTTP协议的最初版本,功能简陋,仅支持 GET 方法,并且仅能请求访问 HTML 格式的资源

  • HTTP/1.0

    • 增加了请求方式 POST 和 HEAD
    • 不再局限于0.9版本的HTML格式,根据Content-Type可以支持多种数据格式,即MIME多用途互联网邮件扩展,例如text/html、image/jpeg等
    • 同时也开始支持 cache,就是当客户端在规定时间内访问统一网站,直接访问cache即可
    • HTTP请求和回应的格式也变了。除了数据部分,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。其他的新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等
    • 但是1.0版本的工作方式是每次TCP连接只能发送一个请求,当服务器响应后就会关闭这次连接,下一个请求需要再次建立TCP连接,就是不支持keepalive
  • HTTP/1.0+

    在20世纪90年代中叶,为满足飞快发展的万维网,很多流行的 Web 客户端和服务器飞快的向 HTTP 中添加各种特性,包括持久的 keep-alive 连接、虚拟主机支持,以及代理连接支持都被假如到 HTTP 中,并称为非官方的事实标准。这种非正式的 HTTP 扩展版本通常称为 HTTP/1.0+

  • HTTP/1.1

    • http1.1是目前最为主流的http协议版本,从1997年发布至今,仍是主流的http协议版本。
    • 引入了持久连接,或叫长连接( persistent connection),即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive。
    • 引入了管道机制( pipelining),即在同一个TCP连接里,客户端可以同时发送多个请求,进一步改进了HTTP协议的效率。
    • 新增方法:PUT、 PATCH、 OPTIONS、 DELETE。
    • http协议不带有状态,每次请求都必须附上所有信息。请求的很多字段都是重复的,浪费带宽,影响速度。
  • HTTP/2.0(又名 HTTP-NG)

    • http/2发布于2015年,目前应用还比较少。
    • http/2是一个彻底的二进制协议头信息和数据体都是二进制,并且统称为"帧"(frame):头信息帧和数据帧。
    • 复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,且不用按顺序一一对应,避免了队头堵塞的问题,此双向的实时通信称为多工( Multiplexing)
    • HTTP/2 允许服务器未经请求,主动向客户端发送资源,即服务器推送。
    • 引入头信息压缩机制( header compression) ,头信息使用gzip或compress压缩后再发送

HTTP 1.0和HTTP 1.1的主要区别是什么?

  1. 缓存处理,在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
  2. 带宽优化及网络连接的使用,HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
  3. 错误通知的管理,在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
  4. Host头处理,在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。
  5. 长连接,HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。

HTTP 要传送一条报文时,会以流的形式将报文数据的内容通过一条打开的 TCP 连接按序传输。TCP 收到数据流之后,会将数据流砍成被称作段的小数据块,并将段 封装在IP分组中,通过因特网进行传输。所有这些工作都是由 TCP/ IP 软件来处理的,HTTP 程序员什么都看不到。

在任意时刻计算机都可以有几条 TCP 连接处于打开状态。TCP 是通过端口号来保持所有这些连接持续不断地运行。

IP 地址可以将你连接到正确的计算机, 而端口号则可以将你连接到正确的应用程序上去。

image-20210609120910672.png HTTP 事务的时延有以下几种主要原因。

  1. 客户端首先需要根据 URI 确定 Web 服务器的 IP 地址和端口号。如果最近没有对 URI 中的主机名进行访问,通过 DNS 解析系统将 URI 中的主机名转换成一个 IP 地址可能要花费数十秒的时间 3 。
  2. 接下来,客户端会向服务器发送一条 TCP 连接请求,并等待服务器回送一个请 求接受应答。每条新的 TCP 连接都会有连接建立时延。这个值通常最多只有一 两秒钟,但如果有数百个 HTTP 事务的话,这个值会快速地叠加上去。
  3. 一旦连接建立起来了,客户端就会通过新建立的 TCP 管道来发送 HTTP 请求。 数据到达时,Web 服务器会从 TCP 连接中读取请求报文,并对请求进行处理
  4. 然后,Web 服务器会回送 HTTP 响应,这也需要花费时间。

HTTP连接的处理

串行连接

假设有一 个包含了 3 个嵌入图片的 Web 页面。浏览器需要发起 4 个 HTTP 事务来显示此页面: 1个用于顶层的 HTML 页面,3 个用于嵌入的图片。如果每个事务都需要(串行地建 立)一条新的连接,那么连接时延和慢启动时延就会叠加起来。

image-20210205153656493.png

并行连接

通过多条 TCP 连接发起并发的 HTTP 请求。

HTTP 允许客户端打开多条连接,并行地执行多个 HTTP 事务。在这个例子中,并行加载了四幅嵌入式图片,每个事务都有自己的TCP连接

image-20210205153903601.png

一个连接到速度较快服务器上的 HTTP 事务就会很容易地耗尽所有可用的 Modem 带宽。如果并行加载多个对象,每个对象都会去竞争这有限的带宽,每个对象都会以较慢的速度按比例加载,这样带来的性能提升就很小,甚至没什么提升。

但如前所述,即使实 际上它们并没有加快页面的传输速度,并行连接通常也会让用户觉得页面加载得更快了,因为多个组件对象同时出现在屏幕上时,用户能够看到加载的进展。如果整个屏幕上有很多动作在进行,即使实际上秒表显示整个页面的下载时间更长,人们也会认为 Web 页面加载得更快一些。

并行连接也有一些缺点:

  • 每个事务都会打开 / 关闭一条新的连接,会耗费时间和带宽。
  • 由于 TCP 慢启动特性的存在,每条新连接的性能都会有所降低。
  • 可打开的并行连接数量实际上是有限的

持久连接

重用 TCP 连接,以消除连接及关闭时延。

image-20210205165604142.png

Web 客户端经常会打开到同一个站点的连接,初始化了对某服务器 HTTP 请求的应用程序很可能会在不久的将来对那台服务器发起更多的请求(比如,获取在线图片)。这种性质被称为站点局部性(site locality)

HTTP/1.1(以及 HTTP/1.0 的各种增强版本)允许 HTTP 设备在事务处理结束之后将 TCP 连接保持在打开状态,以便为未来的 HTTP 请求重用现存的连接。

非持久连接会在 每个事务结束之后关闭。持久连接会在不同事务之间保持打开状态,直到客户端或服务器决定将其关闭为止。

持久连接降低了时延和连接建立的开销, 将连接保持在已调谐状态,而且减少了打开连接的潜在数量。但是,管理持久连接时要特别小心,不然就会累积出大量的空闲连接,耗费本地以及远程客户端和服务器上的资源。

持久连接与并行连接配合使用可能是最高效的方式。现在,很多 Web 应用程序都会打开少量的并行连接,其中的每一个都是持久连接。持久连接有两种类型:比较老的HTTP/1.0+“keep-alive”连接,以及现代的 HTTP/1.1“persistent”连接。

keep-Alive 首部只是请求将连接保持在活跃状态。发出 keep-alive 请求之后,客户端和服务器并不一定会同意进行 keep-alive 会话。它们可以在任意时刻关 闭空闲的 keep-alive 连接,并可随意限制 keep-alive 连接所处理事务的数量。Keep-Alive 首部完全是可选的,但只有在提供 Connection: Keep-Alive 时才能使用它。

HTTP/1.1 逐渐停止了对keep-alive连接的支持,用一种名为持久连接(persistent connection)的改进型设计取代了它。

与 HTTP/1.0+ 的 keep-alive 连接不同,HTTP/1.1 持久连接在默认情况下是激活的。除非特别指明,否则 HTTP/1.1 假定所有连接都是持久的。要在事务处理结束之后将连接关闭,HTTP/1.1 应用程序必须向报文中显式地添加一个Connection: close 首部。这是与以前的 HTTP 协议版本很重要的区别,在以前的版本中,keepalive 连接要么是可选的,要么根本就不支持。

管道化连接

通过共享的TCP连接发起并发的HTTP请求。

image-20210205165648268.png

HTTP/1.1 允许在持久连接上可选地使用请求管道。在响应到达之前,可以将多条请求放入队列。当第一条请求通过网络 流向地球另一端的服务器时,第二条和第三条请求也可以开始发送了。

对管道化连接有几条限制

  • 如果 HTTP 客户端无法确认连接是持久的,就不应该使用管道。
  • 必须按照与请求相同的顺序回送 HTTP 响应。HTTP 报文中没有序列号标签,因此如果收到的响应失序了,就没办法将其与请求匹配起来了。
  • HTTP 客户端必须做好连接会在任意时刻关闭的准备,还要准备好重发所有未完成的管道化请求
  • HTTP 客户端不应该用管道化的方式发送会产生副作用的请求(比如 POST)

image-20210205160949515.png

HTTPS

HTTP缺点:

  1. 通信使用明文不对数据进行加密(内容容易被窃听)
  2. 不验证通信方身份(容易伪装)
  3. 无法确定报文完整性(内容易被篡改)

HTTP 协议的实现本身非常简单,不论是谁发送过来的请求都会 返回响应,因此不确认通信方,会存在以下各种隐患。

  • 无法确定请求发送至目标的 Web 服务器是否是按真实意图返回响应的那台服务器。有可能是已伪装的 Web 服务器。
  • 无法确定响应返回到的客户端是否是按真实意图接收响应的那个客户端。有可能是已伪装的客户端。
  • 无法确定正在通信的对方是否具备访问权限。因为某些 Web 服务器上保存着重要的信息,只想发给特定用户通信的权限。
  • 无法判定请求是来自何方、出自谁手。 即使是无意义的请求也会照单全收。
  • 无法阻止海量请求下的 DoS 攻击(Denial of Service,拒绝服务攻击)。

因此,HTTP 协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。

为了解决 HTTP 协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议 HTTPS,为了数据传输的安全,HTTPS 在 HTTP 的基础上加入了 SSL(安全套接层)协议,SSL 依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。

与 SSL(安全套接层)组合使用的 HTTP 就是 HTTPS

image-20210416092915432.png

HTTP 和 HTTPS 对比

HTTP 协议传输的数据都是未加密的,也就是明文的,因此使用 HTTP 协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了 SSL(Secure Sockets Layer)协议用于对 HTTP 协议传输的数据进行加密,从而就诞生了 HTTPS。简单来说,HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输身份认证的网络协议,要比 HTTP 协议安全。

HTTPS 和 HTTP 的区别主要如下:

  1. https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
  2. http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
  3. http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
  4. http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

对称加密与非对称加密

主要的加密方法分为两种:一种是共享密钥加密(对称密钥加密),一种是公开密钥加密(非对称密钥加密)

共享密钥加密(对称秘钥加密)

加密与解密使用同一个密钥,常见的对称加密算法:DES,AES,3DES等。

image-20210416092948820.png 也就是说在加密的同时,也会把密钥发送给对方。在发送密钥过程中可能会造成密钥被窃取,那么如何解决这一问题呢?

公开密钥(非对称密钥)

公开密钥使用一对非对称密钥。一把叫私有密钥,另一把叫公开密钥。私有密钥不让任何人知道,公有密钥随意发送。公钥加密的信息,只有私钥才能解密。常见的非对称加密算法:RSA,ECC等。

也就是说,发送密文方使用对方的公开密钥进行加密,对方接受到信息后,使用私有密钥进行解密

image-20210416093009892.png

对称加密加密与解密使用的是同样的密钥,所以速度快,但由于需要将密钥在网络传输,所以安全性不高。

非对称加密使用了一对密钥,公钥与私钥,所以安全性高,但加密与解密速度慢。

为了解决这一问题,https 采用对称加密与非对称加密的混合加密方式

SSL/TLS

SSL(Secure Sockets Layer),中文叫做“安全套接层”。它是在上世纪90年代中期,由网景公司设计的。

SSL 协议就是用来解决 HTTP 传输过程的不安全问题,到了1999年,SSL 因为应用广泛,已经成为互联网上的事实标准。IETF 就在那年把 SSL 标准化。标准化之后的名称改为 TLS(是“Transport Layer Security”的缩写),中文叫做“传输层安全协议”。

很多相关的文章都把这两者并列称呼(SSL/TLS),因为这两者可以视作同一个东西的不同阶段。

SSL/TLS协议的基本思路是采用公钥加密法 (opens new window),也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。

但是,这里有两个问题。

  • 如何保证公钥不被篡改?

解决方法:将公钥放在数字证书中。只要证书是可信的,公钥就是可信的。

  • 公钥加密计算量太大,如何减少耗用的时间?

    每一次对话(session),客户端和服务器端都生成一个"对话密钥"(session key),用它来加密信息。由于"对话密钥"是对称加密,所以运算速度非常快,而服务器公钥只用于加密"对话密钥"本身,这样就减少了加密运算的消耗时间。

因此,SSL/TLS协议的基本过程是这样的:

  1. 服务端将非对称加密的公钥发送给客户端;
  2. 客户端拿着服务端发来的公钥,对对称加密的key做加密并发给服务端;
  3. 服务端拿着自己的私钥对发来的密文解密,从而获取到对称加密的key;
  4. 二者利用对称加密的key对需要传输的消息做加解密传输。

HTTPS 相比 HTTP,在请求前多了一个「握手」的环节。

握手过程中确定了数据加密的密码。在握手过程中,网站会向浏览器发送 SSL 证书,SSL 证书和我们日常用的身份证类似,是一个支持 HTTPS 网站的身份证明,SSL 证书里面包含了网站的域名证书有效期证书的颁发机构以及用于加密传输密码的公钥等信息,由于公钥加密的密码只能被在申请证书时生成的私钥解密,因此浏览器在生成密码之前需要先核对当前访问的域名与证书上绑定的域名是否一致,同时还要对证书的颁发机构进行验证,如果验证失败浏览器会给出证书错误的提示。

证书

image-20210416093034994.png

实际上,我们使用的证书分很多种类型,SSL证书只是其中的一种。证书的格式是由 X.509 标准定义。SSL 证书负责传输公钥,是一种PKI(Public Key Infrastructure,公钥基础结构)证书。

我们常见的证书根据用途不同大致有以下几种:

  1. SSL证书,用于加密HTTP协议,也就是HTTPS。
  2. 代码签名证书,用于签名二进制文件,比如Windows内核驱动,Firefox插件,Java代码签名等等。
  3. 客户端证书,用于加密邮件。
  4. 双因素证书,网银专业版使用的USB Key里面用的就是这种类型的证书。

这些证书都是由受认证的证书颁发机构——我们称之为CA(Certificate Authority)机构来颁发,针对企业与个人的不同,可申请的证书的类型也不同,价格也不同。CA机构颁发的证书都是受信任的证书,对于 SSL 证书来说,如果访问的网站与证书绑定的网站一致就可以通过浏览器的验证而不会提示错误。

image-20210205173159964.png

HTTP+ 加密 + 认证 + 完整性保护 =HTTPS

为什么服务端要发送证书给客户端

互联网有太多的服务需要使用证书来验证身份,以至于客户端(操作系统或浏览器等)无法内置所有证书,需要通过服务端将证书发送给客户端。

客户端为什么要验证接收到的证书

中间人攻击

客户端<------------攻击者<------------服务端
        伪造证书            拦截请求

客户端如何验证接收到的证书

为了回答这个问题,需要引入数字签名(Digital Signature)。

+---------------------+
| A digital signature |
|(not to be confused  |
|with a digital       |
|certificate)         |            +---------+              +--------+
| is a mathematical   |----哈希--->| 消息摘要  |---私钥加密--->| 数字签名 |
|technique used       |            +---------+              +--------+
|to validate the      |
|authenticity and     |
|integrity of a       |
|message, software    |
|or digital document. |
+---------------------+

将一段文本通过哈希(hash)和私钥加密处理后生成数字签名。

假设消息传递在Bob,Susan和Pat三人之间发生。Susan将消息连同数字签名一起发送给Bob,Bob接收到消息后,可以这样验证接收到的消息就是Susan发送的

+---------------------+
| A digital signature |
|(not to be confused  |
|with a digital       |
|certificate)         |            +---------+
| is a mathematical   |----哈希--->|  消息摘要 |
|technique used       |            +---------+
|to validate the      |                 |
|authenticity and     |                 |
|integrity of a       |                 |
|message, software    |                 对
|or digital document. |                 比
+---------------------+                 |
                                        |
                                        |
          +--------+               +---------+
          | 数字签名 |---公钥解密--->|  消息摘要 |
          +--------+               +---------+

当然,这个前提是Bob知道Susan的公钥。更重要的是,和消息本身一样,公钥不能在不安全的网络中直接发送给Bob。此时就引入了证书颁发机构(Certificate Authority,简称CA),CA数量并不多,Bob客户端内置了所有受信任CA的证书。CA对Susan的公钥(和其他信息)数字签名后生成证书。

Susan将证书发送给Bob后,Bob通过CA证书的公钥验证证书签名。

Bob信任CA,CA信任Susan 使得 Bob信任Susan,信任链 (Chain Of Trust)就是这样形成的。

事实上,Bob客户端内置的是CA的根证书(Root Certificate),HTTPS协议中服务器会发送证书链(Certificate Chain)给客户端。

HTTPS的工作原理

  1. Client 使用 https 的 URL 访问 Server,要求与 Server 建立 SSL 连接
  2. Server 把事先配置好的公钥证书返回给客户端。
  3. Client 验证公钥证书:比如是否在有效期内,证书的用途是不是匹配 Client 请求的站点,是不是在 CRL 吊销列表里面,它的上一级证书是否有效,这是一个递归的过程,直到验证到根证书(操作系统内置的Root证书或者Client内置的Root证书)。如果验证通过则继续,不通过则显示警告信息。
  4. Client 使用伪随机数生成器生成加密所使用的对称密钥,然后用证书的公钥加密这个对称密钥,发给Server。
  5. Server使用自己的私钥(private key)解密这个消息,得到对称密钥。至此,Client和Server双方都持有了相同的对称密钥。
  6. Server使用对称密钥加密“明文内容A”,发送给Client。
  7. Client使用对称密钥解密响应的密文,得到“明文内容A”。
  8. Client再次发起HTTPS的请求,使用对称密钥加密请求的“明文内容B”,然后Server使用对称密钥解密密文,得到“明文内容B”。

image-20210416093140935.png

HTTPS的优点

尽管 HTTPS 并非绝对安全,掌握根证书的机构、掌握加密算法的组织同样可以进行中间人形式的攻击,但 HTTPS仍是现行架构下最安全的解决方案,主要有以下几个好处:

  1. 使用HTTPS协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;
  2. HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。
  3. HTTPS是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。
  4. 谷歌曾在2014年8月份调整搜索引擎算法,并称“比起同等HTTP网站,采用HTTPS加密的网站在搜索结果中的排名将会更高”。

HTTPS的缺点

虽然说HTTPS有很大的优势,但其相对来说,还是存在不足之处的:

  1. HTTPS协议握手阶段比较费时,会使页面的加载时间延长近50%,增加10%到20%的耗电;
  2. HTTPS连接缓存不如HTTP高效,会增加数据开销和功耗,甚至已有的安全措施也会因此而受到影响;
  3. SSL证书需要钱,功能越强大的证书费用越高,个人网站、小网站没有必要一般不会用。
  4. SSL证书通常需要绑定IP,不能在同一IP上绑定多个域名,IPv4资源不可能支撑这个消耗。
  5. HTTPS协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。最关键的,SSL证书的信用链体系并不安全,特别是在某些国家可以控制CA根证书的情况下,中间人攻击一样可行。

HTTP 切换到 HTTPS

如果需要将网站从http切换到https到底该如何实现呢?

这里需要将页面中所有的链接,例如js,css,图片等等链接都由http改为https。例如:www.baidu.com改为https://www.baidu.…

BTW,这里虽然将http切换为了https,还是建议保留http。所以我们在切换的时候可以做http和https的兼容,具体实现方式是,去掉页面链接中的http头部,这样可以自动匹配http头和https头。例如:将www.baidu.com改为//www.baidu.…

Cookie/Session

Cookie

什么是Cookie,Cookie的使用过程是怎么样的?

由于 http 协议是无状态协议,如果客户通过浏览器访问 web 应用时没有一个保存用户访问状态的机制,那么将不能持续跟踪应用的操作。比如当用户往购物车中添加了商品,web 应用必须在用户浏览别的商品的时候仍保存购物车的状态,以便用户继续往购物车中添加商品。

image-20210205165929864.png

image-20210205165940145.png

image-20210205170020739.png

cookie 是浏览器的一种缓存机制,它可用于维持客户端与服务器端之间的会话。由于下面一题会讲到session,所以这里要强调cookie会将会话保存在客户端(session则是把会话保存在服务端)

这里以最常见的登陆案例讲解cookie的使用过程:

  1. 首先用户在客户端浏览器向服务器发起登陆请求
  2. 登陆成功后,服务端会把登陆的用户信息设置 cookie 中,返回给客户端浏览器
  3. 客户端浏览器接收到 cookie 请求后,会把 cookie 保存到本地(可能是内存,也可能是磁盘,看具体使用情况而定)
  4. 以后再次访问该 web 应用时,客户端浏览器就会把本地的 cookie 带上,这样服务端就能根据 cookie 获得用户信息了

Session

什么是session,有哪些实现session的机制?

session 是一种维持客户端与服务器端会话的机制。但是与 cookie 把会话信息保存在客户端本地不一样,session 把会话保留在浏览器端。

我们同样以登陆案例为例子讲解 session 的使用过程:

  1. 首先用户在客户端浏览器发起登陆请求
  2. 登陆成功后,服务端会把用户信息保存在服务端,并返回一个唯一的 session 标识给客户端浏览器。
  3. 客户端浏览器会把这个唯一的 session 标识保存在起来
  4. 以后再次访问 web 应用时,客户端浏览器会把这个唯一的 session 标识带上,这样服务端就能根据这个唯一标识找到用户信息。

看到这里可能会引起疑问:把唯一的 session 标识返回给客户端浏览器,然后保存起来,以后访问时带上,这难道不是 cookie 吗?

没错,session 只是一种会话机制,在许多 web 应用中,session 机制就是通过 cookie 来实现的。也就是说它只是使用了 cookie 的功能,并不是使用 cookie 完成会话保存。与 cookie 在保存客户端保存会话的机制相反,session 通过 cookie 的功能把会话信息保存到了服务端。

进一步地说,session 是一种维持服务端与客户端之间会话的机制,它可以有不同的实现。以现在比较流行的小程序为例,阐述一个 session 的实现方案:

  1. 首先用户登陆后,需要把用户登陆信息保存在服务端,这里我们可以采用 redis。比如说给用户生成一个 userToken,然后以 userId 作为键,以 userToken 作为值保存到 redis 中,并在返回时把 userToken 带回给小程序端。
  2. 小程序端接收到 userToken 后把它缓存起来,以后每当访问后端服务时就把 userToken 带上。
  3. 在后续的服务中服务端只要拿着小程序端带来的 userToken 和 redis 中的 userToken 进行比对,就能确定用户的登陆状态了。

session和cookie区别

  1. cookie 是浏览器提供的一种缓存机制,它可以用于维持客户端与服务端之间的会话
  2. session 指的是维持客户端与服务端会话的一种机制,它可以通过 cookie 实现,也可以通过别的手段实现。
  3. 如果用 cookie 实现会话,那么会话会保存在客户端浏览器中
  4. 而 session 机制提供的会话是保存在服务端的。

Cookie 和 Session都是⽤来跟踪浏览器⽤户身份的会话⽅式,但是两者的应⽤场景不太⼀样。

Cookie ⼀般⽤来保存⽤户信息 ⽐如

  1. 我们在 Cookie 中保存已经登录过得⽤户信息,下次访问⽹站的 时候⻚⾯可以⾃动帮你登录的⼀些基本信息给填了;
  2. ⼀般的⽹站都会有保持登录也就是说下次你再访 问⽹站的时候就不需要重新登录了,这是因为⽤户登录的时候我们可以存放了⼀个 Token 在 Cookie 中,下次登录的时候只需要根据 Token 值来查找⽤户即可(为了安全考虑,重新登录⼀般要将 Token 重写);
  3. 登录⼀次⽹站后访问⽹站其他⻚⾯不需要重新登录。

Session 的主要作⽤就是通过服务端记录⽤户的状态。 典型的场景是购物⻋,当你要添加商品到购物⻋的时候,系统不知道是哪个⽤户操作 的,因为 HTTP 协议是⽆状态的。服务端给特定的⽤户创建特定的 Session 之后就可以标识这个⽤户 并且跟踪这个⽤户了。

Cookie 存储在客户端中,⽽Session存储在服务器上,相对来说 Session 安全性更⾼。如果要在 Cookie 中存储⼀些敏感信息,不要直接写⼊ Cookie 中,最好能将 Cookie 信息加密然后使⽤到的时候再去服务器端解密。

DNS协议

域名系统(DNS)

image-20210203225758391.png

为了得到层次化的域名空间,设计了域名空间。

image-20210203230236194.png

域名空间信息被分布到多台主机上,这些计算机称为DNS服务器。这些服务器是分级的。

  • 根服务器

    根服务器通常不存储关于这些域的任何信息,而是把它的权限委托给其他的一些服务器,并保存到这些服务器的引用。根服务器有多个,每个根服务器都覆盖了整个域名空间。分布在世界各地。

  • 主服务器

    存储了它所管辖的区的文件。它负责创建、维护和更新这个区文件,将其存储在本地磁盘。

  • 次服务器

    既不创建也不更新区文件。区文件来自主服务器或其他次服务器。若需要更新,就必须由主服务器来进行。

名字地址解析

DNS被设计为客户-服务器程序。需要把地址映射为名字或把名字映射为地址的主机要调用称为解析程序的DNS客户程序。解析程序访问靠的最近的DNS服务器并发出映射请求。若DNS服务器有这个信息,就满足解析程序的要求,否则,或者让解析程序再去找其他的服务器,或者直接请其他服务器提供这个信息。

image-20210205164233247.png

迭代解析

当根域名服务器收到本地域名服务器发出的迭代查询请求时,要么给出所查询的ip地址,要么告诉它下一步应该向哪个顶级域名服务器进行后续的查询。反复上述操作,知道所要解析的域名的ip地址后,把这个结果返回给发起查询的主机。

image-20210203233345967.png

为了提高效率,会用高速缓存将最近查到的ip地址存入,当同一个客户或者另一客户请求相同的ip地址时,就可以从高速缓存快速找到。高速缓存会定期清除TTL到期的映射。