了解 HTTP 和 HTTPS 的通信流程有助于提升我们队通信严谨性、安全性的理解,同时也是一种解决方案的积累。
1.HTTP 连接的建立(基于TCP)
首先看握手部分:
第一次握手:Client 说 Server 你好,我想跟你建立连接
报文里携带有 seq=J 的请求确认信息 SYN=1,表示这是一次握手请求确认,seq=J 序列号是用来给对方做备份的,以防下次由于网络不好,再次发送一样的报文,如果发现序列号已经确认过了则直接丢弃
此时客户端的状态变化: CLOSED(关闭) => SYN_SENT(确认信息已发送)
此时服务端的状态变化:CLOSED(关闭) => SYN_RCVD(确认信息已接收)
第二次握手:Server 说 Client 你好,你可以建立连接
首先报文里有对第一次握手的确认信息 ACK = 1 和 序号确认 ack=J+1,也有 Server 请求与 Client 建立链接的 SYN=1和 seq=K标识
此时客户端的状态变化:SYN_SENT(确认信息已发送) => ESTABLISHED(连接建立)
此时服务端的状态变化:不变
第三次握手:Client 说 Server 我知道了,连接已建立
报文中携带有对 Server 端发来的 seq=K 消息的确认信息 ACK=1 和 ack=K+1
此时客户端的状态变化:不变
此时服务端的状态变化: SYN_RCVD(确认信息已接收)=> ESTABLISHED(连接建立)
到此,三次握手完成,客户端开始向服务端发起请求。
为什么不进行二次握手 ?为什么不进行四次握手 ?因为两次无法保证双方都知道能联系上对方,而四次+就没完没了了。
2.HTTPS连接的建立(基于 SSL\TSL 和 TCP)
由于 HTTPS 的目的是安全,所以会经过比 HTTP 连接更复杂的流程,一切为了安全,首先看一下连接建立流程:
这是比较常见的一张图,但是少了两部分,下面会详细说明:
第一步:服务端拿着 https://+IP 去请求服务端,同时携带有一个随机数 X
第二步:服务端收到后会记录下 X,服务端也生成一个随机数 Y,并且把公钥(证书)一并发给客户端
第三步:客户端收到随机数 Y,并进行公钥(证书)的验证,验证通过后会再生成一个随机数 Z,并用公钥进行加密,把加密后的随机数 Z' 发送给服务端,同时使用 X+Y+Z 共同加密生成 密钥K1
第四步:服务端收到加密后的 Z' 后使用私钥进行解密,得到 Z,再用 X+Y+Z 共同加密生成 密钥K2
第五步:客户端用公钥对 密钥K1 进行加密得到 K1',并传给服务端
第六步:服务端收到加密后的 K1' 用私钥解密得到 K1,与第四步生成的 密钥K2 进行比对,比对一致
第七步:服务端把密钥验证一致后的确认消息返回给客户端,连接建立完毕
HTTPS:一切为了安全
HTTPS 为了保证传输的安全,分别使用了非对称加密和对称加密两种方式,为什么要用这么复杂的加密方式呢 ?
1.对称加密已经够安全了,但是不能解决密钥传递的问题,如果服务端给客户端密钥,那相当于告诉全天下密钥是多少,那HTTPS就是摆设了(因为加密解密算法是公开的),如果客户端给服务端密钥,那如果被截获后,客户端的安全就会收到威胁
2.非对称加密也够安全吧,但是因为大家持有的公钥都是一样的,服务端没办法确认发送过来的消息是不是客户端的真实意愿
3.于是就有了对称加密与非对称加密结合的方式,首先客户端用非对称加密方式把密钥传给服务端,就算被截获,因为外部没有解密对应的私钥,所以是安全的;然后双方再使用约定好的对称密钥进行通信
但是 HTTPS 并不完美,因为存在加密解密的流程,所以性能上肯定不如 HTTP