原文链接:https://www.jianshu.com/p/6f2c2d2f72af
一次完整的http请求大概分为3步:
1、域名解析
2、TCP的三次握手
3、发起http请求
用时序图简单的画了一下流程:
对上图的3个步骤做一一的分解:
一、域名解析:
1、浏览会搜索自身的DNS缓存。
2、搜索操作系统自身的DNS缓存。
3、查找本地的Host文件。
4、浏览器向运营商DNS服务器发起一个域名解析的请求(运营商服务器发起迭代请求:根域名服务 器—>顶级域名服务器)。
5、运营商服务器把结果返回操作系统内核同时缓存起来,操作系统内核把结果返回浏览器,这样浏览器就拿到了对应域名的ip地址。(图里没有画这一步)
二、TCP连接:三次握手,确认连接
1、Client首先发送一个连接试探,ACK=0 表示确认号无效,SYN = 1 表示这是一个连接请求或连接接受报文,同时表示这个数据报不能携带数据,seq = x 表示Client自己的初始序号(seq = 0 就代表这是第0号包),这时候Client进入syn_sent状态,表示客户端等待服务器的回复
2、Server监听到连接请求报文后,如同意建立连接,则向Client发送确认。TCP报文首部中的SYN 和 ACK都置1 ,ack = x + 1表示期望收到对方下一个报文段的第一个数据字节序号是x+1,同时表明x为止的所有数据都已正确收到(ack=1其实是ack=0+1,也就是期望客户端的第1个包),seq = y 表示Server 自己的初始序号(seq=0就代表这是服务器这边发出的第0号包)。这时服务器进入syn_rcvd,表示服务器已经收到Client的连接请求,等待client的确认。
3、Client收到确认后还需再次发送确认,同时携带要发送给Server的数据。ACK 置1 表示确认号ack= y + 1 有效(代表期望收到服务器的第1个包),Client自己的序号seq= x + 1(表示这就是我的第1个包,相对于第0个包来说的),一旦收到Client的确认之后,这个TCP连接就进入Established状态,就可以发起http请求了。
三、建立TCP连接后发起http请求
1、TCP/IP链接建立起来后,浏览器就可以向服务器发送HTTP请求了
2、服务器端接受到了这个请求,根据路径参数,经过后端的一些处理之后,把处理后的结果数据返回给浏览器,比如页面完整的html代码等返回给浏览器
3、浏览器拿到了完整的html代码后,在解析和渲染这个页面的时候,里面的JS,CSS,图片静态资源,他们同样也是一个个http请求,都要经过上面的步骤。
一次完整的https请求
https协议就是http+ssl协议。
一个完整的https包涵以下连接过程:
1、客户端发送https请求。
2、服务端接收到https请求之后,生成公钥和私钥。
3、服务端返回公钥。
4、客服端收到公钥,会验证公钥是否有效,如颁发机构或过期时间等,如果发现异常会抛出异常,提示证书存在问题。如果没有问题,会生成一个随机值,作为客户端的密钥,然后用服务端的公钥加密。
5、加密之后,发给服务端。
6、服务端收到经过加密的密钥,然后用私钥进行解密,得到客户端的密钥,然后服务端把要传输的内容和客户端的密钥进行堆成加密,这样除非知道密钥,否则无法知道传输的内容。
7、服务端将经过加密的内容传给客户端。
8、客户端获取加密内容后,用之前生成的密钥对其进行解密,获取到内容。
中间人劫持攻击:
中间人截取客户端发送给服务器的请求,伪装成客户端与服务器进行通信,并将服务器发给客户端的信息的内容发送给客户端,伪装成服务器与客户端进行通信。此时中间人可以获取客户端与服务端的所有通信内容。使用中间人攻击,必须要让客户端信任中间人的证书。
劫持思路:伪造证书
中间人攻击的预防:
证书校验,针对安全性比较高的app,可以采用客户端预埋证书的方式锁死证书,只有当客户端证书与服务端证书完全一致的情况下才允许通信。证书过期必须强制更新。