HTTP和HTTPS的区别

240 阅读8分钟

这是我参与更文挑战的第6天,活动详情查看: 更文挑战

HTTP是面试常问的基本网络知识,本文略做总结

HTTP简介

HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议, HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)

HTTP请求方式

根据 HTTP 标准,HTTP 请求可以使用多种请求方法

HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD方法

HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法

GET	 请求指定的页面信息,并返回实体主体
HEAD	 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
POST	 向指定资源提交数据进行处理请求。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改
PUT	 从客户端向服务器传送的数据取代指定的文档的内容
DELETE	 请求服务器删除指定的页面
CONNECT	 HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器
OPTIONS	 允许客户端查看服务器的性能
TRACE	 回显服务器收到的请求,主要用于测试或诊断
PATCH	 是对 PUT 方法的补充,用来对已知资源进行局部更新 

HTTP三次握手四次挥手

面试经常会问三次握手和四次挥手的问题,知道握手和挥手的流程以外,我们还需要知道一下原理

三次握手

image.png

  • 客户端发起请求,会想发送一个SYN包,里面包含SYN=1,seq=x(随机数)
  • 服务器收到请求,识别这是一个SYN=1的包(客户端发起请求),服务器随后组装一个ACK包,里面包含SYN=1,ACK=1,ack=x+1(客户端发来的seq+1),seq=y(随机数)
  • 客户端收到ACK包(服务器收到请求),首先会验证ack码是否是SYN包的seq+1的结果,如果符合,那么将会发送一个ACK包给服务器,里面包含ACK=1,ack=y+1
  • 服务器收到ACK包后,验证ACK=1,并且ack码是服务器发送给客户端的ack码+1的结果。

为什么是三次握手?

通过ACK包里的seq进行+1来进行验证发送和接收正常,三次握手就是为了要确保双方的发送功能和接收功能都正常的最少的安全握手次数

四次挥手

image.png

  • 客户端发送FIN包,包含FIN=1,seq=x(随机数),发送FIN包后,客户端不能发送数据,但是能接受数据,等待关闭状态1
  • 服务器收到FIN包,会返回一个ACK包,包含ACK=1,ack=x+1,发送ACK包后,服务器不能接受数据,但是能发送数据
  • 客户端需要等待服务器返回FIN包
  • 服务器发送FIN包,包含FIN=1,seq=y(随机数),发送FIN包后,等待客户端的ACK包。
  • 客户端接受到服务器发送来的FIN包,然后发送一个ACK包,包含ACK=1,ack=y+1
  • 客户端等待2MSL时间,然后关闭连接。
  • 服务器收到客户端ACK包,然后关闭连接。

为什么是四次挥手?

因为当客户端发送FIN包给服务器端的时候,服务器可能这个时候还有数据传输中,所以并不能像三次握手一样,将FIN包和ACK包信息一起发送给客户端,只能先告诉客户端,我收到你的FIN包。服务器将最后的数据发送完毕后,这时才会发送一个FIN包给客户端,客户端收到服务器的FIN包后才会真正进入关闭。同样,服务器收到客户端的ACK包后才会关闭。

客户端收到了FIN包并且发送ACK包给服务器后没有立刻关闭,等待的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。

等待2MSL是因为客户端接收到服务器的FIN包后发送ACK包,客户端并不能确保服务器收到ACK包,如果这时候服务器没有收到ACK包,那么服务器会在一段时间内重新发送FIN包给客户端,这时候客户端接收到FIN包,会从新发送ACK包给服务器,重新进行第四次握手。如果客户端等待时间超过2MSL,那么将会丢弃掉这个链接。

为何使用HTTPS

使用http进行通信的时候,一切都是明文通信,用户与用户之间的通信信息或者密码等敏感信息如果被中间监听,后果会非常严重。所以就需要对http通信的报文进行加密。

  • 使用对称加密:但是使用对称加密方式,就需要双方都知道秘钥,使用相同的秘钥进行加密和解密,但是这里就会有一个问题,就是秘钥的通信,客户端如何知道秘钥是什么呢?如果把秘钥写死在页面中,也是相当容易被破解,如果通过服务器提前将秘钥告知客户端,那么在秘钥的传输过程中,其实中间人也能获取到秘钥,那么加密就没有任何效果了,中间人依然能通过捕获到的秘钥对加密信息进行解密获取明文信息。

  • 非对称加密:发送方使用公钥加密数据,接收方使用私钥解密数据,那么客户端就可以通过请求服务器端,获取服务器的公钥,进行对提交内容的加密,然后服务器用自己的私钥进行解密。但是这里也会有一个问题,就是如果中间人捕获到服务器的公钥,然后拦截到返回中间人的公钥给客户端,那么客户端就会在不知情的情况下,以为这个公钥是目标服务器的公钥,然后利用这个公钥进行数据加密(实际用的是中间人的公钥),这个时候发送加密数据后,中间人就可以利用自己的私钥对数据解密,然后利用目标服务器的公钥加密重新发送给目标服务器,这样就神不知鬼不觉的盗取到加密的明文信息了。主要问题是客户端无法知道获取到公钥是不是目标服务器的。

  • CA证书:CA证书就是一个组织颁发的证书,CA机构通过使用自己的私钥来加密服务器的公钥,并且使用服务器的信息生成一个证书,证书签名也使用CA颁发机构的私钥进行加密。然后我们会得到一个证书文件,并且配置在我们的服务器中,nginx等对https请求会有ssl的配置参数,就是读取这一份文件。那么这个时候客户端向服务器发起请求的时候,服务器将返回这一个证书信息,这时候因为我们系统和浏览器都内置了各大CA机构的公钥信息,那么客户端只需要使用该CA证书颁发机构的公钥对证书进行解密,然后通过一些验证这个证书是否真实有效的(证书所有者,有效期等),如果有效,那么就可以解密出证书内服务器的公钥信息,然后利用这个服务器公钥进行加密信息进行传输。

使用http的时候,我们只是使用tcp进行握手,然后就可以直接开始通信了,但是使用https却要在tcp握手链接成功后,还需要进行SSL/TLS协议进行握手。

四次握手

  • 第一次握手:客户端向服务端发起加密通信的请求,带有支持的协议版本,如TSL1.0,一个客户端生成的随机数,支持的加密算法,支持的压缩算法。

  • 第二次握手:服务器收到客户端请求后,确认加密通信协议版本是否一致,如果版本一致则服务器生成一个随机数,CA证书,确认使用的加密算法,否则关闭加密通信。

  • 第三次握手:客户端收到服务器的返回后,验证证书的合法性,以及解密证书验证等,验证通过后,发送给服务器以下信息:客户端会用CA证书解密出来的服务器公钥对一个随机数进行加密,编码改变通知标识,客户端握手结束通知(包含第一次握手时所有内容的hash值,给服务器进行校验)。

  • 第四次握手:服务器收到后,会返回编码改变通知,服务器握手结束通知(包含第二次握手时所有内容的hash值,给客户端进行校验)。

前3次握手中,都互相生成了一个随机码,而在第三次握手之后,客户端和服务器端都拥有了3个随机码,然而这三个随机码是给服务器和客户端用这3个随机数生成一个秘钥,最终作为对称秘钥的方式进行加密和解密的。在SSL/TSL的四次握手后,就会继续进行http协议通信了