HTTP和HTTPS详解

1-HTTP

1.1-HTTP介绍

HTTP 是一种 超文本传输协议(Hypertext Transfer Protocol)HTTP 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范

HTTP 主要内容分为三部分,超文本(Hypertext)、传输(Transfer)、协议(Protocol)

  • 超文本就是不单单只是本文,它还可以传输图片、音频、视频,甚至点击文字或图片能够进行超链接的跳转。
  • 上面这些概念可以统称为数据,传输就是数据需要经过一系列的物理介质从一个端系统传送到另外一个端系统的过程。通常我们把传输数据包的一方称为请求方,把接到二进制数据包的一方称为应答方
  • 而协议指的就是是网络中(包括互联网)传递、管理信息的一些规范。如同人与人之间相互交流是需要遵循一定的规矩一样,计算机之间的相互通信需要共同遵守一定的规则,这些规则就称为协议,只不过是网络协议。

设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。

HTTP有多个版本,目前广泛使用的是HTTP/1.1版本。

1.2-HTTP原理和工作流程

1. HTTP原理

HTTP是一个基于TCP/IP通信协议来传递数据的协议,传输的数据类型为HTML 文件,、图片文件, 查询结果等。

HTTP协议一般用于B/S架构,浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。

HTTP是一个客户端和服务器端请求和应答的标准(TCP)。客户端是终端用户,服务器端是网站。通过使用Web浏览器、网络爬虫或者其它的工具,客户端发起一个到服务器上指定端口(默认端口为80)的HTTP请求。(我们称这个客户端)叫用户代理(user agent)。应答的服务器上存储着(一些)资源,比如HTML文件和图像。(我们称)这个应答服务器为源服务器(origin server)。在用户代理和源服务器中间可能存在多个中间层,比如代理,网关,或者隧道(tunnels)。尽管TCP/IP协议是互联网上最流行的应用,HTTP协议并没有规定必须使用它和(基于)它支持的层。 事实上,HTTP可以在任何其他互联网协议上,或者在其他网络上实现。HTTP只假定(其下层协议提供)可靠的传输,任何能够提供这种保证的协议都可以被其使用。

通常,由HTTP客户端发起一个请求,建立一个到服务器指定端口(默认是80端口)的TCP连接。HTTP服务器则在那个端口监听客户端发送过来的请求。一旦收到请求,服务器(向客户端)发回一个状态行,比如”HTTP/1.1 200 OK”,和(响应的)消息,消息的消息体可能是请求的文件、错误消息、或者其它一些信息。HTTP使用TCP而不是UDP的原因在于(打开)一个网页必须传送很多数据,而TCP协议提供传输控制,按顺序组织数据,和错误纠正。

2. HTTP原理

一次HTTP操作称为一个事务,其工作过程大概如下:

  1. 用户在浏览器中键入需要访问网页的URL或者点击某个网页中链接;
  2. 浏览器根据URL中的域名,通过DNS解析出目标网页的IP地址;(然后将上面结合本机自己的信息,封装成一个http请求数据包)
  3. 在HTTP开始工作前,客户端首先会通过TCP/IP协议来和服务端建立链接(TCP三次握手)
  4. 建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可内容。
  5. 服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
  6. 一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码:Connection:keep-alive,TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。

1.3-HTTP特点

  1. http协议支持客户端/服务端模式,也是一种请求/响应模式的协议。
  2. 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。
  3. 灵活:HTTP允许传输任意类型的数据对象。传输的类型由Content-Type加以标记。
  4. 无连接:限制每次连接只处理一个请求。服务器处理完请求,并收到客户的应答后,即断开连接,但是却不利于客户端与服务器保持会话连接,为了弥补这种不足,产生了两项记录http状态的技术,一个叫做Cookie,一个叫做Session。
  5. 无状态:无状态是指协议对于事务处理没有记忆,后续处理需要前面的信息,则必须重传。

1.4-URI和URL的区别

HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。

  • URI:Uniform Resource Identifier 统一资源标识
  • URL:Uniform Resource Location 统一资源定位

URI 是用来标识一个具体的资源的,我们可以通过 URI 知道一个资源是什么。

URL 则是用来定位具体的资源的,标示了一个具体的资源位置。互联网上的每个文件都有一个唯一的URL。

1.5-HTTP的报文及其结构

1. 请求报文

HTTP 请求报文大致可分为请求行、请求头、空行、请求主体四部分。请求行、请求头部和空行是必需的而报文主体是可选的,每个部分结尾都用空行来作为结束标志。

  • 请求行:请求方法(Method) + 空格 + 统一资源标识符(URI) + 空格 + HTTP版本 + CR LF ;

    • 请求方法:GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT

      最常用的是GETPOST

    • URL字段用来指明目标资源的位置,它只包含一个完整URL中的文件路径和查询字符串这两部分,比如”/index.php?id=24”,而不包含协议、主机名和端口号。如果同一服务器上部署了多个网站,那么为了准确判断出请求的是哪个资源需要将URL字段和Host请求头的值(指定要访问的网站名)相结合使用。

    • 协议版本字段说明该请求报文属于哪一版的http协议,比如HTTP/1.1或HTTP/1.0。

  • 请求头:字段名 + 冒号 + 值 + CR LF ;

    请求头部用来告知服务器该请求和客户端本身的一些额外信息,每个请求头都是一个键值对,键和值之间用英文冒号隔开。每个请求头单独形成一行,它们的末尾都是一个回车符和换行符。

    在所有的请求头中,只有Host是必需的,其它请求头都是可选的。这里,我们将一些常见的请求头列于下表中:

  • 空行: 回车符(CR)+ 换行符(LF) ;

    在请求头部的后面是一个空行,它只包含一个回车符和一个换行符,不包含其它任何内容,连空格也不能包含。这个空行用于标记请求头部已结束;它是必须要有的,即便使用GET这样不包含报文主体的请求方法时也要有这个空行。

  • 请求体: 由用户自定义添加,如post的body等;

2. 响应报文

HTTP响应报文状态行、响应头、空行、响应主体四部分,响应报文结构与请求报文结构唯一的区别在于第一行中用状态信息代替了请求信息。状态行(status line)通过提供一个状态码来说明所请求的资源情况。

状态行:HTTP版本 + 空格 + 状态码 + 空格 + 状态码描述 + CR LF ;

响应头:字段名 + 冒号 + 值 + CR LF ;

空行: 回车符(CR)+ 换行符(LF) ;

响应体: 由用户自定义添加,如post的body等;

响应报文示例:

1.6-Get和Post的区别

HTTP 中包括许多方法,Get 和 Post 是 HTTP 中最常用的两个方法,基本上使用 HTTP 方法中有 99% 都是在使用 Get 方法和 Post 方法,所以有必要我们对这两个方法有更加深刻的认识。

  • get 方法一般用于请求,比如你在浏览器地址栏输入 www.cxuanblog.com 其实就是发送了一个 get 请求,它的主要特征是请求服务器返回资源,而 post 方法一般用于``

    表单的提交,相当于是把信息提交给服务器,等待服务器作出响应,get 相当于一个是 pull/拉的操作,而 post 相当于是一个 push/推的操作。

  • get 方法是不安全的,因为你在发送请求的过程中,你的请求参数会拼在 URL 后面,从而导致容易被攻击者窃取,对你的信息造成破坏和伪造;

    /test/demo_form.asp?name1=value1&name2=value

    而 post 方法是把参数放在请求体 body 中的,这对用户来说不可见。

    POST /test/demo_form.asp HTTP/1.1
    Host: w3schools.com
    name1=value1&name2=value2
  • get 请求的 URL 有长度限制,而 post 请求会把参数和值放在消息体中,对数据长度没有要求。

  • get 请求会被浏览器主动 cache,而 post 不会,除非手动设置。(get请求数据会被浏览器缓存)

  • get 请求在浏览器反复的 回退/前进 操作是无害的,而 post 操作会再次提交表单请求。

  • get 请求在发送过程中会产生一个 TCP 数据包;post 在发送过程中会产生两个 TCP 数据包。对于 get 方式的请求,浏览器会把 http header 和 data 一并发送出去,服务器响应 200(返回数据);而对于 post,浏览器先发送 header,服务器响应 100 continue,浏览器再发送 data,服务器响应 200 ok(返回数据)。

  • get请求的URL可以被保存为浏览器书签,而post请求不行。

1.7-HTTP是无状态协议?

无状态协议(Stateless Protocol) 就是指浏览器对于事务的处理没有记忆能力。举个例子来说就是比如客户请求获得网页之后关闭浏览器,然后再次启动浏览器,登录该网站,但是服务器并不知道客户关闭了一次浏览器。

HTTP 就是一种无状态的协议,他对用户的操作没有记忆能力。可能大多数用户不相信,他可能觉得每次输入用户名和密码登陆一个网站后,下次登陆就不再重新输入用户名和密码了。这其实不是 HTTP 做的事情,起作用的是一个叫做 小甜饼(Cookie) 的机制。它能够让浏览器具有记忆能力。

如果你的浏览器允许 cookie 的话,查看方式 chrome://settings/content/cookies

当你向服务端发送请求时,服务端会给你发送一个认证信息,服务器第一次接收到请求时,开辟了一块 Session 空间(创建了Session对象),同时生成一个 sessionId ,并通过响应头的 Set-Cookie:JSESSIONID=XXXXXXX 命令,向客户端发送要求设置 Cookie 的响应;客户端收到响应后,在本机客户端设置了一个 JSESSIONID=XXXXXXX 的 Cookie 信息,该 Cookie 的过期时间为浏览器会话结束;

接下来客户端每次向同一个网站发送请求时,请求头都会带上该 Cookie信息(包含 sessionId ), 然后,服务器通过读取请求头中的 Cookie 信息,获取名称为 JSESSIONID 的值,得到此次请求的 sessionId。这样,你的浏览器才具有了记忆能力。

2. JWT

还有一种方式是使用 JWT 机制,它也是能够让你的浏览器具有记忆能力的一种机制。与 Cookie 不同,JWT 是保存在客户端的信息,它广泛的应用于单点登录的情况。JWT 具有两个特点

  • JWT 的 Cookie 信息存储在客户端,而不是服务端内存中。也就是说,JWT 直接本地进行验证就可以,验证完毕后,这个 Token 就会在 Session 中随请求一起发送到服务器,通过这种方式,可以节省服务器资源,并且 token 可以进行多次验证。
  • JWT 支持跨域认证,Cookies 只能用在单个节点的域或者它的子域中有效。如果它们尝试通过第三个节点访问,就会被禁止。使用 JWT 可以解决这个问题,使用 JWT 能够通过多个节点进行用户认证,也就是我们常说的跨域认证

1.8-HTTP响应状态码

状态代码由服务器发出,以响应客户端对服务器的请求。

  • 1xx(信息):收到请求,继续处理
  • 2xx(成功):请求已成功接收,理解和接受
  • 3xx(重定向):需要采取进一步措施才能完成请求
  • 4xx(客户端错误):请求包含错误的语法或无法满足
  • 5xx(服务器错误):服务器无法满足明显有效的请求

1. 1xx(信息)

  • 100:客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应。服务器必须在请求完成后向客户端发送一个最终响应。
  • 101:服务器已经理解了客户端的请求,并将通过Upgrade 消息头通知客户端采用不同的协议来完成这个请求。在发送完这个响应最后的空行后,服务器将会切换到在Upgrade 消息头中定义的那些协议。只有在切换新的协议更有好处的时候才应该采取类似措施。例如,切换到新的HTTP 版本比旧版本更有优势,或者切换到一个实时且同步的协议以传送利用此类特性的资源。
  • 102:由WebDAV(RFC 2518)扩展的状态码,代表处理将被继续执行。

2. 2xx(成功)

  • 200:请求已成功,请求所希望的响应头或数据体将随此响应返回。

  • 201:请求已经被实现,而且有一个新的资源已经依据请求的需要而建立,且其 URI 已经随Location 头信息返回。假如需要的资源无法及时建立的话,应当返回 ‘202 Accepted’。

  • 202:服务器已接受请求,但尚未处理。正如它可能被拒绝一样,最终该请求可能会也可能不会被执行。在异步操作的场合下,没有比发送这个状态码更方便的做法了。返回202状态码的响应的目的是允许服务器接受其他过程的请求(例如某个每天只执行一次的基于批处理的操作),而不必让客户端一直保持与服务器的连接直到批处理操作全部完成。在接受请求处理并返回202状态码的响应应当在返回的实体中包含一些指示处理当前状态的信息,以及指向处理状态监视器或状态预测的指针,以便用户能够估计操作是否已经完成。

  • 203:服务器已成功处理了请求,但返回的实体头部元信息不是在原始服务器上有效的确定集合,而是来自本地或者第三方的拷贝。当前的信息可能是原始版本的子集或者超集。例如,包含资源的元数据可能导致原始服务器知道元信息的超级。使用此状态码不是必须的,而且只有在响应不使用此状态码便会返回200 OK的情况下才是合适的。

  • 204:服务器成功处理了请求,但不需要返回任何实体内容,并且希望返回更新了的元信息。响应可能通过实体头部的形式,返回新的或更新后的元信息。如果存在这些头部信息,则应当与所请求的变量相呼应。如果客户端是浏览器的话,那么用户浏览器应保留发送了该请求的页面,而不产生任何文档视图上的变化,即使按照规范新的或更新后的元信息应当被应用到用户浏览器活动视图中的文档。由于204响应被禁止包含任何消息体,因此它始终以消息头后的第一个空行结尾。

  • 205:告诉用户代理(浏览器)重置发送该请求的文档。服务器成功处理了请求,且没有返回任何内容。但是与204响应不同,返回此状态码的响应要求请求者重置文档视图。该响应主要是被用于接受用户输入后,立即重置表单,以便用户能够轻松地开始另一次输入。与204响应一样,该响应也被禁止包含任何消息体,且以消息头后的第一个空行结束。

  • 206:服务器已经成功处理了部分 GET 请求。类似于 FlashGet 或者迅雷这类的 HTTP 下载工具都是使用此类响应实现断点续传或者将一个大文档分解为多个下载段同时下载。

    当客户端使用Range请求头时,返回该状态码。  

    该请求必须包含 Range 头信息来指示客户端希望得到的内容范围,并且可能包含 If-Range 来作为请求条件。响应必须包含如下的头部域:   

    Content-Range 用以指示本次响应中返回的内容的范围;如果是 Content-Type 为 multipart/byteranges 的多段下载,则每一 multipart 段中都应包含 Content-Range 域用以指示本段的内容范围。假如响应中包含 Content-Length,那么它的数值必须匹配它返回的内容范围的真实字节数。

  • 207:由WebDAV(RFC 2518)扩展的状态码,代表之后的消息体将是一个XML消息,并且可能依照之前子请求数量的不同,包含一系列独立的响应代码。

3. 3xx(重定向)

  • 300:返回多个响应,需要浏览器或者用户选择,请求的资源可在多处得到;

  • 301:永久重定向,在Location响应首部的值仍为当前URL(隐式重定向);

    请求资源的URL被永久的改变,新的URL会在响应的Location中给出。

    浏览器到新的URL重新请求资源,因为有些客户端会把请求方式method改成GET。所以该状态码建议GET和HEAD方法中使用。

  • 302:临时重定向,在Location响应首部的值仍为新的URL(显示重定向);

    请求资源的URL被暂时修改到Location提供的URL。未来可能还会有新的修改。

    浏览器会根据新的URL重新请求资源。有些客户端会把方法method改为GET,建议在GET和HEAD方法中使用。

  • 303:建议客户端访问其他URL或访问方式,服务通过返回的响应数据指导客户端通过GET方法去另一个URL获取资源,通常用于POST或者PUT的请求返回结果,重定向到信息提示页面或者进度展示页面。

    重定向页面的方法是GET方法。

  • 304:Not Modified 请求的资源没有改变,可以继续使用缓存,服务器根据请求头判断,需要资源未修改,只返回响应头;否则将资源一起返回。

  • 305:请求的资源必须从服务器指定的地址得。

  • 306:在最新版的规范中,306状态码已经不再被使用。

  • 307:临时重定向,基本和302相同。

    唯一的区别是这个状态码严格禁止浏览器到新URL请求资源时修改原来的请求方式和请求体。

    就是说原来使用POST,这次还是要使用POST。

    如果想要用PUT方法去修改一个服务器上没有的资源,可以用303状态码

    如果想要把一个POST方法改为GET,请使用303。

  • 308:永久重定向。基本和301相同。但是严格禁止修改请求方式和请求体。

4. 4xx(客户端错误)

  • 400:错误请求。由于语法错误,该请求无法完成;没有host请求头字段,或者设置了超过一个的host请求头字段。
  • 401:未经授权。服务器拒绝响应,客户端未授权该请求。缺乏有效的身份认证凭证,一般可能是未登陆。登陆后一般都解决问题。
  • 403:服务器已经理解请求,但是拒绝执行它。与401响应不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交。如果这不是一个 HEAD 请求,而且服务器希望能够讲清楚为何请求不能被执行,那么就应该在实体内描述拒绝的原因。当然服务器也可以返回一个404响应,假如它不希望让客户端获得任何信息。
  • 404:URL无效或者URL有效但是没有资源。
  • 405:请求方式Method不允许。但是GET和HEAD属于强制方式,不能返回这个状态码。
  • 406:资源类型不符合服务器要求,请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体。
  • 407:与401响应类似,只不过客户端必须在代理服务器上进行身份验证。代理服务器必须返回一个 Proxy-Authenticate 用以进行身份询问。客户端可以返回一个 Proxy-Authorization 信息头用以验证。
  • 408:请求超时。客户端没有在服务器预备等待的时间内完成一个请求的发送。客户端可以随时再次提交这一请求而无需进行任何更改。
  • 426:告诉客户端需要升级通信协议。

5. 5xx(服务器错误)

  • 500:服务器内部错误,未捕获。
  • 501:服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法,并且无法支持其对任何资源的请求。
  • 502:作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
  • 503:无法服务。一般发生在因维护而停机或者服务过载,由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。如果能够预计延迟时间,那么响应中可以包含一个 Retry-After 头用以标明这个延迟时间。如果没有给出这个 Retry-After 信息,那么客户端应当以处理500响应的方式处理它。
  • 504:网关超时。服务器作为网关或者代理,不能及时从上游服务器获取响应返回给客户端。
  • 505:发出的请求http版本服务器不支持。如果请求通过http2发送,服务器不支持http2.0,就会返回该状态码。

1.9-HTTP-1.0、HTTP-1.1和HTTP-2.0

1. HTTP-1.0

HTTP 1.0 是在 1996 年引入的,从那时开始,它的普及率就达到了惊人的效果。

  • HTTP 1.0 仅仅提供了最基本的认证,这时候用户名和密码还未经加密,因此很容易收到窥探。
  • HTTP 1.0 被设计用来使用短链接,即每次发送数据都会经过 TCP 的三次握手和四次挥手,效率比较低。
  • HTTP 1.0 只使用 header 中的 If-Modified-Since 和 Expires 作为缓存失效的标准。
  • HTTP 1.0 不支持断点续传,也就是说,每次都会传送全部的页面和数据。
  • HTTP 1.0 认为每台计算机只能绑定一个 IP,所以请求消息中的 URL 并没有传递主机名(hostname)。

2. HTTP-1.1

HTTP 1.1 是 HTTP 1.0 开发三年后出现的,也就是 1999 年,它做出了以下方面的变化

  • HTTP 1.1 使用了摘要算法来进行身份验证
  • HTTP 1.1 默认使用长连接,长连接就是只需一次建立就可以传输多次数据,传输完成后,只需要一次切断连接即可。长连接的连接时长可以通过请求头中的 keep-alive 来设置
  • HTTP 1.1 中新增加了 E-tag,If-Unmodified-Since, If-Match, If-None-Match 等缓存控制标头来控制缓存失效。
  • HTTP 1.1 支持断点续传,通过使用请求头中的 Range 来实现。
  • HTTP 1.1 使用了虚拟网络,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。

HTTP-1.1缺陷:

  • 队头阻塞

    队头阻塞是指当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一并被阻塞,会导致客户端迟迟收不到数据。

    针对队头阻塞:

    1. 将同一页面的资源分散到不同域名下,提升连接上限。虽然能公用一个 TCP 管道,但是在一个管道中同一时刻只能处理一个请求,在当前的请求没有结束之前,其他的请求只能处于阻塞状态。

    2. 减少请求数量

    3. 内联一些资源:css、base64 图片等

    4. 合并小文件减少资源数

  • 无状态特性

    无状态是指协议对于连接状态没有记忆能力。纯净的 HTTP 是没有 cookie 等机制的,每一个连接都是一个新的连接。上一次请求验证了用户名密码,而下一次请求服务器并不知道它与上一条请求有何关联,换句话说就是掉登录态

  • 不安全性

    传输内容没有加密,中途可能被篡改和劫持。

3. HTTP-2.0

HTTP 2.0 是 2015 年开发出来的标准,它主要做的改变如下

  • 头部压缩,由于 HTTP 1.1 经常会出现 User-Agent、Cookie、Accept、Server、Range 等字段可能会占用几百甚至几千字节,而 Body 却经常只有几十字节,所以导致头部偏重。HTTP 2.0 使用 HPACK 算法进行压缩。使用专门的 HPACK 算法,每次请求和响应只发送差异头部,一般可以达到 50% ~90% 的高压缩率。
  • 二进制格式,HTTP 2.0 使用了更加靠近 TCP/IP 的二进制格式,而抛弃了 ASCII 码,提升了解析效率
  • 强化安全,由于安全已经成为重中之重,所以 HTTP2.0 一般都跑在 HTTPS 上。
  • 多路复用,即每一个请求都是是用作连接共享。一个请求对应一个id,这样一个连接上可以有多个请求。
  • 请求优先级,虽然无限的并发流解决了队头阻塞的问题,但如果带宽受限,客户端可能会因防止堵塞通道而阻止请求。在网络通道被非关键资源堵塞时,高优先级的请求会被优先处理。
  • 服务端推送服务端推送(ServerPush),可以让服务端主动把资源文件推送给客户端。当然客户端也有权利选择是否接收。

2-HTTPS

2.1-什么是HTTPS?

维基百科对 HTTPS 的解释是:

超文本传输安全协议(英语:HyperText Transfer Protocol Secure,缩写:HTTPS;常称为 HTTP over TLS、HTTP over SSL 或 HTTP Secure)是一种通过计算机网络进行安全通信的传输协议。HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包。HTTPS 开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。这个协议由网景公司(Netscape)在 1994 年首次提出,随后扩展到互联网上。

抓重点:HTTPS=HTTP over SSL/TLS,也就是说,HTTPS 在传输层 TCP 和应用层 HTTP 之间,多走了一层 SSL/TLS。

由此可见,TLS/SSL 是 HTTPS 的核心! SSL和TLS都是加密协议SSL,全称 Secure Socket Layer,在 1994 年由网景公司(Netscape)最早提出 1.0 版本;TLS,全称 Transport Layer Security,则是 1999 年基于 SSL3.0 版本上改进而来的。官方建议弃用 SSL 而保留和采用 TLS,但是由于历史原因,SSL 仍然存在,而且很多人已经习惯 SSL 这个名词,因此现在索性就叫成 SSL/TLS。

  • HTTP协议(HyperText Transfer Protocol,超文本传输协议)是大家最熟悉的一种协议,它是一个用于传输超媒体文档的协议,它位于OSI网络协议模型的应用层。但是它是明文传输协议,是非常不安全的,容易被人篡改和窃取数据。
  • SSL(Secure Socket Layer) —— 网景(Netscape)公司设计的主要用于web的安全传输协议。它位于TCP传输层协议和应用层协议之间。(它没有被划分在OSI网络协议模型中,且认为它是应用层的子层。)
  • 众所周知,网景公司20世纪90年代在和微软的竞争中最终败下阵来,之后网景公司将SSL协议的管理权转交给IETF(Internet Engineering Task Force, www.ietf.org)。于是IETF将SSL作了标准化,重新命名为TLS.xn--ietfssl%2Ctls-o68q04a8c50mt9nhxfc5e1qcb41ewo6bpjcqwqez6w/)(Transport Layer Security)。在1999年,TLS 1.0诞生了(其实也就是SSL 3.1)。
  • HTTPS(HyperText Transfer Protocol Secure)是建立在SSL/TLS协议之上,信息通信通过SSL/TLS进行加密,最后一个S就是Secure的缩写,代表安全的意思,HTTPS = HTTP + SSL/TLS

2.2-为什么需要HTTPS?

肯定有不少同学不假思索:“当然是 HTTP 不安全,HTTPS 安全,所以选择 HTTPS 呗!”那么,HTTPS 比 HTTP“好”在哪里?

维基百科上对 HTTP 的解释如下:

设计 HTTP 最初的目的是为了提供一种发布和接收 HTML 页面的方法。

HTTP 的发展是由蒂姆·伯纳斯-李于 1989 年在欧洲核子研究组织(CERN)所发起。HTTP 的标准制定由万维网协会(World Wide Web Consortium,W3C)和互联网工程任务组(Internet Engineering Task Force,IETF)进行协调,最终发布了一系列的 RFC,其中最著名的是 1999 年 6 月公布的 RFC 2616,定义了 HTTP 协议中现今广泛使用的一个版本——HTTP 1.1。

HTTP 协议是为了传输网页超文本(文本、图像、多媒体资源),以及规范客户端和服务器端之间互相请求资源的方法的应用层协议。在 1989 年最早推出了 HTTP 0.9 版本,而 1999 年公布的 HTTP 1.1 是到目前(2020 年)仍旧广泛使用的版本(引自《HTTP 协议几个版本的比较》)。

但是这个 HTTP 1.1 版本存在一个很大的问题-明文传输(Plaintext/Clear Text),这个问题在互联网时代的今天是致命的,一旦数据在公共网络中被第三方截获,其通信内容轻而易举地就被窃取了。

因此,HTTPS 应运而生,它被公认的三大优势有:

  1. 数据加密,防窃听
  2. 身份验证,防冒充
  3. 完整性校验,防篡改

第 1 点确实是解决了 HTTP 明文传输;至于第 2 和第 3 点,其他一些应用层协议也会遇到(服务端被冒充、数据被篡改是网络传输中“较常见”的问题)。

  • 保护隐私(Privacy):所有信息都是加密传播,第三方无法窃听数据。如果使用HTTP明文传输数据的话,很可能被第三方劫持数据,那么所输入的密码或者其他个人资料都被暴露在他人面前,后果可想而知。
  • 数据完整性(Integraty):一旦第三方篡改了数据,接收方会知道数据经过了篡改,这样便保证了数据在传输过程中不被篡改 —— 数据的完整性。
  • 身份认证(Identification):第三方不可能冒充身份参与通信,因为服务器配备了由证书颁发机构(Certificate Authority,简称CA)颁发的安全证书,可以证实服务器的身份信息,防止第三方冒充身份。(也有少数情况下,通信需要客户端提供证书,例如银行系统,需要用户在登录的时候,插入银行提供给用户的USB,就是需要客户端提供证书,用来验证客户的身份信息。)

2.3-SSL/TLS的工作原理

我们探讨 HTTPS 的握手过程,其实就是 SSL/TLS 的握手过程。

TLS 旨在为 Internet 提供通信安全的加密协议。TLS 握手是启动和使用 TLS 加密的通信会话的过程。在 TLS 握手期间,Internet 中的通信双方会彼此交换信息,验证密码套件,交换会话密钥。

每当用户通过 HTTPS 导航到具体的网站并发送请求时,就会进行 TLS 握手。除此之外,每当其他任何通信使用HTTPS(包括 API 调用和在 HTTPS 上查询 DNS)时,也会发生 TLS 握手。

TLS 具体的握手过程会根据所使用的密钥交换算法的类型和双方支持的密码套件而不同。我们以RSA 非对称加密来讨论这个过程。

需要理解SSL/TLS的工作原理,我们需要掌握加密算法。加密算法有两种:对称加密和非对称加密:

  • 对称加密:通信双方使用相同的密钥进行加密。特点是加密速度快,但是缺点是需要保护好密钥,如果密钥泄露的话,那么加密就会被别人破解。常见的对称加密有AES,DES算法。
  • 非对称加密:它需要生成两个密钥:公钥(Public Key)和私钥(Private Key)。公钥顾名思义是公开的,任何人都可以获得,而私钥是私人保管的。相信大多程序员已经对这种算法很熟悉了:我们提交代码到github的时候,就可以使用SSH key:在本地生成私钥和公钥,私钥放在本地.ssh目录中,公钥放在github网站上,这样每次提交代码,不用麻烦的输入用户名和密码了,github会根据网站上存储的公钥来识别我们的身份。公钥负责加密,私钥负责解密;或者,私钥负责加密,公钥负责解密。这种加密算法安全性更高,但是计算量相比对称加密大很多,加密和解密都很慢。常见的非对称算法有RSA。

SSL/TLS是利用了对称加密和非对称加密的特点。先来看下整个SSL/TLS的握手过程:

  • 在进行通信前,首先会进行 HTTP 的三次握手,握手完成后,再进行 TLS 的握手过程
  • ClientHello:客户端通过向服务器发送 hello 消息来发起握手过程。这个消息中会夹带着客户端支持的 TLS 版本号(TLS1.0 、TLS1.2、TLS1.3) 、客户端支持的密码套件、以及一串 客户端随机数
  • ServerHello:在客户端发送 hello 消息后,服务器会发送一条消息,这条消息包含了服务器的 SSL 证书、服务器选择的密码套件和服务器生成的随机数。
  • 认证(Authentication):客户端的证书颁发机构会认证 SSL 证书,然后发送 Certificate 报文,报文中包含公开密钥证书。最后服务器发送 ServerHelloDone 作为 hello 请求的响应。第一部分握手阶段结束。
  • 加密阶段:在第一个阶段握手完成后,客户端会发送 ClientKeyExchange 作为响应,这个响应中包含了一种称为 The premaster secret 的密钥字符串,这个字符串就是使用上面公开密钥证书进行加密的字符串。随后客户端会发送 ChangeCipherSpec,告诉服务端使用私钥解密这个 premaster secret 的字符串,然后客户端发送 Finished 告诉服务端自己发送完成了。

Session key 其实就是用公钥证书加密的公钥。

  • 实现了安全的非对称加密:然后,服务器再发送 ChangeCipherSpecFinished 告诉客户端解密完成,至此实现了 RSA 的非对称加密。

2.4-HTTPS的工作原理

HTTPS的整体过程分为证书验证和数据传输阶段,具体的交互过程如下:

① 证书验证阶段

  1. 浏览器发起 HTTPS 请求
  2. 服务端返回 HTTPS 证书
  3. 客户端验证证书是否合法,如果不合法则提示告警

② 数据传输阶段

  1. 当证书验证合法后,在本地生成随机数
  2. 通过公钥加密随机数,并把加密后的随机数传输到服务端
  3. 服务端通过私钥对随机数进行解密
  4. 服务端通过客户端传入的随机数构造对称加密算法,对返回结果内容进行加密后传输

2.5-为什么数据传输是用对称加密?

首先,非对称加密的加解密效率是非常低的,而 http 的应用场景中通常端与端之间存在大量的交互,非对称加密的效率是无法接受的;

另外,在 HTTPS 的场景中只有服务端保存了私钥,一对公私钥只能实现单向的加解密,所以 HTTPS 中内容传输加密采取的是对称加密,而不是非对称加密。

2.6-为什么需要 CA 认证机构颁发证书?

HTTP 协议被认为不安全是因为传输过程容易被监听者勾线监听、伪造服务器,而 HTTPS 协议主要解决的便是网络传输的安全性问题。

首先我们假设不存在认证机构,任何人都可以制作证书,这带来的安全风险便是经典的 “中间人攻击” 问题。
“中间人攻击”的具体过程如下:

过程原理:

  1. 本地请求被劫持(如DNS劫持等),所有请求均发送到中间人的服务器
  2. 中间人服务器返回中间人自己的证书
  3. 客户端创建随机数,通过中间人证书的公钥对随机数加密后传送给中间人,然后凭随机数构造对称加密对传输内容进行加密传输
  4. 中间人因为拥有客户端的随机数,可以通过对称加密算法进行内容解密
  5. 中间人以客户端的请求内容再向正规网站发起请求
  6. 因为中间人与服务器的通信过程是合法的,正规网站通过建立的安全通道返回加密后的数据
  7. 中间人凭借与正规网站建立的对称加密算法对内容进行解密
  8. 中间人通过与客户端建立的对称加密算法对正规内容返回的数据进行加密传输
  9. 客户端通过与中间人建立的对称加密算法对返回结果数据进行解密

由于缺少对证书的验证,所以客户端虽然发起的是 HTTPS 请求,但客户端完全不知道自己的网络已被拦截,传输内容被中间人全部窃取。

2.7-浏览器是如何确保 CA 证书的合法性?

1. 证书包含什么信息?

  • 颁发机构信息
  • 公钥
  • 公司信息
  • 域名
  • 有效期
  • 指纹
  • ……

2. 证书的合法性依据是什么?

首先,权威机构是要有认证的,不是随便一个机构都有资格颁发证书,不然也不叫做权威机构。另外,证书的可信性基于信任制,权威机构需要对其颁发的证书进行信用背书,只要是权威机构生成的证书,我们就认为是合法的。所以权威机构会对申请者的信息进行审核,不同等级的权威机构对审核的要求也不一样,于是证书也分为免费的、便宜的和贵的。

3. 浏览器如何验证证书的合法性?

浏览器发起 HTTPS 请求时,服务器会返回网站的 SSL 证书,浏览器需要对证书做以下验证:

  1. 验证域名、有效期等信息是否正确。证书上都有包含这些信息,比较容易完成验证;

  2. 判断证书来源是否合法。每份签发证书都可以根据验证链查找到对应的根证书,操作系统、浏览器会在本地存储权威机构的根证书,利用本地根证书可以对对应机构签发证书完成来源验证;

  3. 判断证书是否被篡改。需要与 CA 服务器进行校验;

  4. 判断证书是否已吊销。通过CRL(Certificate Revocation List 证书注销列表)和 OCSP(Online Certificate Status Protocol 在线证书状态协议)实现,其中 OCSP 可用于第3步中以减少与 CA 服务器的交互,提高验证效率

以上任意一步都满足的情况下浏览器才认为证书是合法的。

这里插一个我想了很久的但其实答案很简单的问题:
既然证书是公开的,如果要发起中间人攻击,我在官网上下载一份证书作为我的服务器证书,那客户端肯定会认同这个证书是合法的,如何避免这种证书冒用的情况?

其实这就是非加密对称中公私钥的用处,虽然中间人可以得到证书,但私钥是无法获取的,一份公钥是不可能推算出其对应的私钥,中间人即使拿到证书也无法伪装成合法服务端,因为无法对客户端传入的加密数据进行解密。

5. 只有认证机构可以生成证书吗?

如果需要浏览器不提示安全风险,那只能使用认证机构签发的证书。但浏览器通常只是提示安全风险,并不限制网站不能访问,所以从技术上谁都可以生成证书,只要有证书就可以完成网站的
HTTPS 传输。例如早期的 12306 采用的便是手动安装私有证书的形式实现 HTTPS 访问。

2.8-本地随机数被窃取怎么办?

证书验证是采用非对称加密实现,但是传输过程是采用对称加密,而其中对称加密算法中重要的随机数是由本地生成并且存储于本地的,HTTPS
如何保证随机数不会被窃取?

其实 HTTPS 并不包含对随机数的安全保证,HTTPS
保证的只是传输过程安全,而随机数存储于本地,本地的安全属于另一安全范畴,应对的措施有安装杀毒软件、反木马、浏览器升级修复漏洞等。

2.9-用了 HTTPS 会被抓包吗?

HTTPS 的数据是加密的,常规下抓包工具代理请求后抓到的包内容是加密状态,无法直接查看。

但是,正如前文所说,浏览器只会提示安全风险,如果用户授权仍然可以继续访问网站,完成请求。因此,只要客户端是我们自己的终端,我们授权的情况下,便可以组建中间人网络,而抓包工具便是作为中间人的代理。通常
HTTPS
抓包工具的使用方法是会生成一个证书,用户需要手动把证书安装到客户端中,然后终端发起的所有请求通过该证书完成与抓包工具的交互,然后抓包工具再转发请求到服务器,最后把服务器返回的结果在控制台输出后再返回给终端,从而完成整个请求的闭环。

既然 HTTPS 不能防抓包,那 HTTPS 有什么意义?
HTTPS可以防止用户在不知情的情况下通信链路被监听,对于主动授信的抓包操作是不提供防护的,因为这个场景用户是已经对风险知情。要防止被抓包,需要采用应用级的安全防护,例如采用私有的对称加密,同时做好移动端的防反编译加固,防止本地算法被破解。

参考

——https://mp.weixin.qq.com/s/1o270rwqrDC2rGfgSqTUuA

——https://mp.weixin.qq.com/s/DsnzPiGdciJM-_TM6tbmyQ

——https://mp.weixin.qq.com/s/FyB3Dlg0_2LpIF1x1ElIPA

——https://mp.weixin.qq.com/s/DsnzPiGdciJM-_TM6tbmyQ