【TCP/IP】HTTP协议与HTTPS的加密流程

1、HTTP基础知识

HTTP全称Hyper Text Transfer Protocol,即超文本传输协议。HTTP是一个应用层协议,可视为一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范。面试

1. HTTP请求流程

咱们这里就直接以一个常见的面试题引入啦。算法

在浏览器中输入 www.baidu.com 后会发生什么?数据库

当一个用户在浏览器里输入 www.baidu.com 这个 URL 时,将会发生不少操做。首先它会请求 DNS 把这个域名解析成对应的 IP 地址,而后根据这个 IP 地址在互联网上找到对应的服务器,向这个服务器发起一个GET 请求,由这个服务器决定返回默认的数据资源给访问用户。在服务器端实际上还有很复杂的逻辑:服务器可能有好多台,到底指定哪台服务器来处理请求,这须要一个负载均衡设备来平均分配全部用户的请求;还有请求的数据是存储在分布式缓存里仍是一个静态文件中,或是在数据库里;当数据返回浏览器时,浏览器解析数据发现还有一些静态资源(如 CSS、JS 或者图片)时又会发起另外的 HTTP 请求,而这些请求有可能会在 CDN 上,那么 CDN 服务器又会处理这个用户的请求,大致上一个用户请求会涉及这么多操做。每个细节都会影响这个请求最终是否会成功。后端

咱们不去涉及其中过多的知识,单说HTTP的请求流程便可,从上面咱们知道,HTTP协议是由客户端发起的,由请求和响应构成,是一个标准的客户端服务器模型(C/S),它的具体流程以下:浏览器

  1. 地址解析。域名系统DNS解析域名获得主机的IP地址;缓存

  2. 封装HTTP请求数据包。封装的内容有以上部分结合本机本身的信息;安全

  3. 封装成TCP包,创建TCP链接(TCP的三次握手);服务器

  4. 客户机发送请求命令。 创建链接后,客户机向服务器发送一个请求;markdown

  5. 服务器响应。服务器接到请求后,给予相应的响应信息;网络

  6. 服务器关闭TCP链接。通常Web服务器向浏览器发送了请求数据,它要关闭TCP链接;

  7. 客户端解析报文。客户端接收到响应报文后解析HTML代码,并渲染。

2. 常见状态码

HTTP常见的状态码分为五大类,以下表所示:

状态码类别 具体含义 常见状态码
1xx 提示信息,表示目前是协议处理的中间状态,还须要后续的操做
2xx 成功,报文已经收到并被正确处理 200、20四、206
3xx 重定向,资源位置发生变更,须要客户端从新发送请求 30一、30二、304
4xx 客户端错误,请求报文有误,服务器没法处理; 400、40三、404
5xx 服务器错误,服务器在处理请求时内部发生了错误。 500、50一、50二、503
  • 1xx:1xx类状态码属于提示信息,是协议处理中的一种中间状态,实际用到的比较少。

  • 2xx:2xx类状态码表示成功处理了客户端需求,也是咱们浏览器发起请求时常见的状态:

    • 【200 OK】:最多见的成功状态码,表示一切正常。若是是非HEAD请求,服务器返回的响应头都会有 body 数据;
    • 【204 No Content】:也是常见的成功状态码,与 200 OK 基本相同,但响应头没有 body 数据;
    • 【206 Partial Content】:是应用于 HTTP 分块下载或断点续传,表示响应返回的 body 数据并非资源的所有,而是其中的一部分,也是服务器处理成功的状态;
  • 3xx:3xx类状态码表示客户端请求的资源发生了变更,须要客户端用新的 URL 从新发送请求获取资源,也就是重定向

    • 【301 Moved Permanently】:表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问;
    • 【302 Found】:表示临时重定向,说明请求的资源还在,但暂时须要用另外一个 URL 来访问;

    注:301 和 302 都会在响应头里使用Location,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。

  • 4xx:4xx类状态码表示客户端发送的报文有误,服务器没法处理,也就是错误码的含义:

    • 【400 Bad Request】:表示客户端请求的报文有错误,但只是个笼统的错误;
    • 【403 Forbidden】:表示服务器禁止访问资源,并非客户端的请求出错;
    • 【404 Not Found】:表示请求的资源在服务器上不存在或未找到,因此没法提供给客户端。
  • 5xx:5xx类状态码表示客户端请求报文正确,可是服务器处理时内部发生了错误,属于服务器端的错误码:

    • 【500 Internal Server Error】:与400相似,是个笼统通用的错误码,服务器发生了什么错误,咱们并不知道;
    • 【501 Not Implement】:表示客户端请求的功能还不支持,相似”即将开业,尽情期待“的意思;
    • 【502 Bad Gatwy】:一般是服务器做为网关或代理时返回的错误码,表示服务器自身工做正常,访问后端服务器发生了错误;
    • 【503 Service Unavailable】:表示服务器当前很忙,暂时没法响应服务器,相似”网络服务正忙,请稍后重试“的意思。

3. 常见字段

首先咱们了解一下HTTP的报文结构,大概以下:

这是常见的请求报文,固然还有响应报文,二者之间并不彻底一致,这里只简单说起一下请求报文的格式。

首先是请求方法,常见的请求方法有 GET和POST两种,以后跟着的是URL,即要访问的地址,再后面跟着的就是协议版本,如:HTTP/1.1。

咱们主要讲解以后跟着的字段,即请求头,请求头的字段常以key-value的形式,即”属性名:属性值“的形式传递若干数据,服务端据此获取客户端的信息。接下来咱们就来了解常见的字段:

  • Accept字段与Content-type字段:

Accept字段用于客户端向服务器发送报文时表示本身可接收的响应内容类型,如:Accept:text/plain (文本类型);

相似的字段还有Accept-Charset 表示可接收的字符集;Accept-Encoding表示可接受的响应内容的压缩方式 ;Accept-Language表示可接受的响应内容语言列表; Accept-Datetime表示可接受的按照时间来表示的响应内容版本。

Content-Type字段用于服务器回应时,告诉客户端,本次数据的格式是什么。

相似的字段还有Content-Encoding字段表示数据的压缩方法,表示服务器返回的数据使用什么压缩格式。

  • Host字段

    Host字段用于客户端发送请求时,用来指定服务器的域名。例如:Host:www.baidu.com。这里须要与报文中的请求行的 URL 区分,Host字段与 URL 组成完整的请求URL,例如请求行中的URL为/getPerson,而Host字段为www.baidu.com,那么二者结合起来就是www.baidu.com/getPerson

  • Connection字段

    Connection字段最经常使用于客户端要求服务器使用 TCP 持久链接,以便其余请求复用。

    Connection: keep-alive

    扩展:

    • HTTP是无状态的面向链接的协议,无状态并不表明HTTP不能保持TCP链接,HTTP使用的不是UDP(无链接);

    • HTTP/1.1 版本的默认链接都是持久链接,但为了兼容老版本的 HTTP,须要指定Connection首部字段的值为Keep-Alive。简单的说,当一个网页打开完成后,客户端和服务器之间用于传输的 HTTP 数据的 TCP 链接不会马上关闭,若是客户端再次访问这个服务器上的网页,会继续使用这一条已经创建的链接;

    • Keep-Alive不会永久保持链接,它有一个保持时间,能够在不一样的服务器软件(如Apache)中设定这个时间。

  • Content-Length字段

    服务器在返回数据时,会有Content-Length字段,代表本次回应的数据长度。例如:Content-Length: 1000,这代表了服务器本次回应的数据长度是1000个字节,后面的字节就属于下一个回应了。

2、 HTTP存在的问题

1. 性能问题

在 HTTP/1.0 中有很大的性能问题,每次发起一个HTTP请求,都须要去创建一次TCP链接,并且仍是串行请求,这使得 HTTP 在 TCP 的链接创建上花费了大量的开销。对于这种问题,HTTP/1.1 中提出了长链接的通讯方式,也叫持久链接。这种链接的好处在于减小了 TCP 链接的重复创建和断开所形成的额外开销,减轻了服务器端的负载:

HTTP/1.1 采用了长链接的方式,这使得管道(Pipeline)网络传输成为了可能。便可在同一个 TCP 链接里面,客户端能够发起多个请求,只要第一个请求发出去了,没必要等其回来,就能够发第二个请求出去,能够减小总体的响应时间。

可是服务器仍是按照顺序,先回应第一个请求,完成后再回应第二个请求,以此类推。要是前面的请求回应得特别慢,后面就会有许多请求阻塞着,这就是所谓的【队头阻塞】。

因此 HTTP/1.0 或是 HTTP/1.1 性能都不是很完美,因此后续会有其余增强。

2. 安全问题

HTTP的内容是明文传输的,明文数据会通过中间代理服务器、路由器、WIFI热点、通讯服务运行商等多个物理节点,若是信息在传输过程当中被劫持,传输的内容久彻底暴露了,劫持者还能够篡改传输的信息且不被双方察觉,这就是中间人攻击

总结一下,HTTP在安全方面有如下三个问题:

  • 使用明文通讯,一些重要的内容会被窃听;
  • 不能验证对方身份,多是伪造的信息;
  • 没法验证报文的完整性,有可能被修改;

3、HTTPS的实现

针对上面咱们提到的HTTP的安全问题,HTTPS 在 HTTP 的基础上增长了加密处理、认证机制和完整性保护,咱们能够将 HTTPS = HTTP + 加密 + 认证 + 完整性保护

1. 加密

由于 HTTP 使用明文传输,中间会通过多个物理节点,可能会被劫持窃听,针对这一问题,HTTPS 采用了加密的方式解决。最容易理解的就是对称加密。

1.1 对称加密

对称加密好理解,就是咱们拥有一个密钥,它能够用来对一段内容进行加密,一样的,在内容被进行加密后,须要用同一个密钥对加密内容进行解密,才能看到本来的内容,能够看做咱们平常生活中的钥匙。

HTTP 能够直接使用对称加密吗?

固然不能够。若是通讯双方各自持有同一个密钥,且没有第三方知晓,那么这两方之间的通讯安全是能够被保证的(毕竟密钥被破解可能性不大)。问题是”如何使得这个密钥可让传输的双方知晓,同时不被别人知道“?

假如咱们如今浏览器生成一个密钥而后发送到服务端,告诉服务端咱们双方用这个密钥来加密传输文件。或者是放过来,由服务器生成密钥而后发送给浏览器。很明显这就不现实,咱们知道 HTTP 传输时中间是须要通过许多个中间节点的,在通过中间节点时这个密钥被劫持下来是一件十分容易的事,因此这种方式不可取。由此引入非对称加密

1.2 非对称加密

非对称加密有两把密钥,一般一把叫作公钥,另一把叫作私钥。用公钥加密的内容必须用私钥才能解开,一样的,私钥加密的内容须要用公钥才能解开。

HTTP 能够直接使用非对称加密吗?

仍是不能够。鉴于非对称加密的性质,咱们可能会有这种思路:服务器先把公钥直接明文传输给浏览器,以后浏览器向服务器传数据前都先用这个公钥加密好再传输,这条数据彷佛能够保障了,由于只有服务器端的相应私钥能解开这条数据。可是这样仍是有问题,密钥仍是能够被劫持的。

若是服务器用它的的私钥加密数据传给浏览器,那么浏览器用公钥能够解密它,而这个公钥是一开始经过明文传输给浏览器的,若是这个公钥被谁劫持到的话,他也能用该公钥解密服务器传来的信息了。因此这种方式的实现仍是会有问题,彷佛只能保证由浏览器传输数据时的安全性(其实还有漏洞)。

1.3 改良版非对称加密

经过一组公钥、私钥已经能保证单个方向传输的安全性,那用两组公钥私钥是否是就能保证双向传输都安全了,如下面流程为例:

  1. 某网站拥有用于非对称加密的公钥 A、私钥 A‘,浏览器拥有用于非对称加密的公钥 B、私钥 B’ ;
  2. 浏览器向网站服务器发起请求,服务器把公钥 A 明文传输给浏览器;
  3. 浏览器将公钥 B 明文传输给服务器;
  4. 以后浏览器向服务器传输的全部东西都用公钥 A 加密,服务器收到后用私钥 A’ 解密。因为只有服务器拥有这个私钥 A’ 能够解密,因此能保证这条数据的安全;
  5. 服务器向浏览器传输的全部东西都用公钥 B 加密,浏览器收到后用私钥 B’ 解密。同上也能够保证这条数据的安全。

这种实现方式理论上确实可行,抛开这里面仍有的漏洞不谈(下文再述),HTTPS 的加密却没有使用这种方案,为何?

最主要的缘由是非对称加密算法很是耗时,特别是加密解密一些较大数据的时候有些力不从心。相比之下,对称加密就要快不少,那能不能同时运用对称加密与非对称加密的性质来实现对 HTTP 的加密呢?

1.4 混合加密

既然非对称加密耗时,那么就用“对称加密 + 非对称加密”结合的形式来实现对 HTTP 的加密,并且还得尽可能减小非堆成加密的次数 ,这样是否能实现呢?

这种方式是能够实现的,并且非对称加密、解密各只须要用一次便可。请看如下过程:

  1. 某网站拥有非对称加密的公钥 A、私钥 A‘ ;
  2. 浏览器向网站服务器发起请求,服务器把公钥 A 明文传输给浏览器;
  3. 浏览器随机生成一个用以对称加密的密钥 X,用公钥 A 加密后传给服务器;
  4. 服务器端拿到加密的密钥后,用公钥 A 解密获得密钥 X;
  5. 这样双方就都拥有密钥 X 了,且别人没法知道它,以后双方全部数据都用密钥 X 进行加密解密。

HTTPS 基本上就是采用了这种方案了,固然这种方法仍是有漏洞,咱们接着往下讲。

2. 认证

2.1 中间人攻击

根据上面的混合加密过程,中间人确实没法拥有浏览器生成的对称密钥 X,这个密钥自己就被公钥 A 给加密了,只有服务器才能经过私钥 A‘ 对其进行解密。然而在这个过程当中中间人彻底不须要获取到密钥 A’ 就能进行攻击了。以下流程所示:

  1. 某网站拥有用于非对称加密的公钥A、私钥A’ ;
  2. 浏览器向网站服务器发起请求,服务器把公钥 A 明文给传输浏览器;
  3. 中间人劫持到公钥A,保存下来,把数据包中的公钥A替换成本身伪造的公钥B(它固然也拥有公钥B对应的私钥B’)
  4. 浏览器随机生成一个用于对称加密的密钥X,用公钥B(浏览器不知道公钥被替换了)加密后传给服务器;
  5. 中间人劫持后用私钥 B’ 解密获得密钥 X,再用公钥 A 将 X 加密后传给服务器
  6. 服务器拿到后用私钥A’解密获得密钥X。

这样在双方都不会发生异常的状况下,中间人获得了密钥 X,这其中的根本缘由就是浏览器没法确认本身收到的公钥是否是网站的。那么接下来就是要解决这一问题。

2.2 数字证书

如何证实浏览器收到的公钥必定是该网站的公钥?这里就须要有一个公信机构给网站颁发一个“身份证”了。网站在使用 HTTPS 前,须要向“CA机构”申请颁发一份数字证书,数字证书里有证书持有者、证书持有者的公钥等信息,服务器把证书传输给浏览器,浏览器从证书里取公钥就好了,证书就如同身份证同样,能够证实“该公钥对应该网站”。

然而到这里仍是有一个问题,如何保证证书在传输的过程不会被篡改,身份证自己有防伪的技术,那么如何保证证书的防伪呢?

2.3 数字签名

如何保证证书不被篡改?

咱们把证书内容生成一份“签名”,比对证书内容和签名是否一致就能察觉是否被修改,这种技术就称为数字签名

数字签名的制做过程?

  1. CA 拥有非对称加密的私钥和公钥;
  2. CA 对证书明文信息进行 Hash;
  3. 对 Hash 后的值用私钥加密,获得数字签名S;

将明文和数字签名共同组成数字证书,这样一份证书就能够颁发给网站了。

浏览器获得证书后如何验证这份证书的真实性?

  1. 拿到服务器发送过来的证书,获得明文T,数字签名S;
  2. 用CA机构的公钥对 S 解密(因为是浏览器信任的机构,因此浏览器保有CA的公钥),获得S‘;
  3. 浏览器用证书说明的 Hash 算法对明文 T 进行 Hash 获得 T’;
  4. 比较 S‘ 是否等于 T’,等于则表明证书可信。

浏览器如何获得权威机构的公钥?

上面提到,如何要对服务器发过来的证书进行解密,那么就须要到CA的公钥,由于其被CA的私钥给加密了。那么浏览器是如何拥有CA的公钥呢?

实际上权威机构的公钥并不须要传输,由于权威机构会和主流的浏览器或操做系统合做,将他们的公钥内置在浏览器或操做系统环境中。客户端收到证书以后,只须要从证书中找到权威机构的信息,并从本地环境中找到权威机构的公钥,就能正确解密A公钥。固然实际状况要比这个复杂得多,这里简单介绍就行。

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

上面咱们提到,权威机构的公钥是可能在浏览器或操做系统中的,那么中间人劫持到证书后是能够解密获得原文的。相应的,他也能够去篡改证书的原文,可是因为他没有 CA 机构的私钥,没法相应地篡改签名。因此浏览器收到证书后会发现原文和解密后的值不一致,说明证书已经被篡改,证书不可信了,因此中间人不可能去篡改证书了。

4、HTTPS的请求流程

  1. 客户端向服务器发起 HTTPS 请求,链接到服务器的 443 端口;
  2. 服务器端有一个密钥对,即公钥和私钥,是用来进行非对称加密使用的,服务器端保存着私钥,不能将其泄露,公钥能够发送给任何人;
  3. 服务器将本身的公钥包含在权威机构发布的证书中发送给客户端;
  4. 客户端收到服务器端的证书以后,会对证书进行检查,验证其合法性,若是发现发现证书有问题,那么HTTPS传输就没法继续。严格的说,这里应该是验证服务器发送的数字证书的合法性,关于客户端如何验证数字证书的合法性。若是公钥合格,那么客户端会生成一个随机值,这个随机值就是用于进行对称加密的密钥,咱们将该密钥称之为client key,即客户端密钥,这样在概念上和服务器端的密钥容易进行区分。而后用服务器的公钥对客户端密钥进行非对称加密,这样客户端密钥就变成密文了,至此,HTTPS中的第一次HTTP请求结束;
  5. 客户端会发起 HTTPS 中的第二个 HTTP 请求,将被公钥所加密以后的客户端密钥发送给服务器;
  6. 服务器接收到客户端发来的密文以后,会用本身的私钥对其进行非对称解密,解密以后的明文就是客户端密钥,而后用客户端密钥对数据进行对称加密,这样数据就变成了密文。
  7. 而后服务器用对称加密的密钥(即客户端密钥)对报文进行加密,并将加密后的报文发送给客户端;
  8. 客户端收到服务器发送来的密文,用客户端密钥对其进行对称解密,获得服务器发送的数据。这样 HTTPS 中的第二个 HTTP 请求结束,整个 HTTPS 传输完成。

文章内容绝大数来源网络,我只是个搬运工,如有哪里出错,请评论区指出。

参考资料:

相关文章
相关标签/搜索