HTTPS在HTTP和TCP之间建立了一个安全连接层 。SSL/TLS层次和TCP很类似,双方建立TCP连接之后,需要再建立安全连接。与TCP连接一样,SSL连接本质上,是对双方安全信息的记录,并不是一个真正意义上的连接。HTTP通过安全连接,即可与目标主机进行安全的通信,不怕被监听、篡改、冒充身份。
这里的SSL与TLS指的都是安全协议。SSL全名Secure Sockets Layer,安全套接字层协议;TLS全名Transport Layer Security,安全传输层协议。TLS从SSL发展而来,SSL是早期的安全层协议;后期逐渐发现了其安全漏洞,发展出了TLS。现在使用的最多的是TLS1.2、TLS1.3版本,如我们查看掘金的证书:
可以看到使用了TLS1.2版本。安全协议版本需要通信双方进行协商,只有使用相同版本的协议,才能建立安全连接。
此外,建立安全连接是比较消耗性能的。如果每次请求都建立一次安全连接,那么网络的效率将会大打折扣。因此,在建立一次安全连接之后,服务器会存储客户端的安全相关信息,在一定时间内通信时无需再次建立安全连接,服务器会把先前的密钥等信息发送给客户端,直接使用此前已经记录的安全信息即可。
安全连接建立流程和TCP连接类同,安全连接也需要一个建立的流程。但是经过了前面HTTPS加密算法以及证书体系的学习,理解HTTPS安全连接建立流程就非常简单了。基本就是把上面的流程走了一遍。先来看一张总体图:
客户端请求服务器建立安全连接,附加客户端支持的SSL与TLS版本、支持的加密算法版本、随机数。
加密算法与安全协议版本有很多,但服务不一定支持最新版本的协议预算法。所以客户端把所以支持的版本发送给服务器,让服务器去选择。
随机数非常重要,前面讲hash算法的时候讲到,随机数是一个动态因子,让hash算法更加安全。同时,随机数也参与了对称密钥的生成。
服务器响应请求,附加选择的协议版本、加密算法版本、服务器随机数。
服务器从客户端支持的协议版本中,选择一套自己最喜欢的。
为了辨别消息是由哪一方加密并发出的,需要准备两个对称密钥。因此服务器也需要产生一个随机数。
服务器向客户端发送证书
服务器向客户端发送自己证书,其中就包含了服务器的公钥。
服务器发送hello done表示hello阶段结束
客户端验证证书,拿到服务器公钥;利用两个随机数,生成pre-master secret,并使用服务器的公钥加密发送给服务器。
证书验证步骤参考上面的证书小节;
pre-master secret是一个非常重要的东西,双方利用pre-master secret生成master-secret,利用前面的两个随机数生成两个对称加密密钥和两个HMAC密钥,两对密钥分别用于客户端加密和服务器加密。
客户端发送changeCipherSpec提示服务器此后使用pre-master secret产生的密钥加密通信
客户端发送FIN报文,表示结束
服务器也发送changeCipherSpec报文
服务器也发送FIN报文,表示结束
双方可以开始安全通信了
至此,对于HTTPS的加密流程,已经比较清晰了。
Android中运用无论是HTTP还是HTTPS,事实上开源网络框架都已经为我们完成了这些粗活累活,例如okHttp。正常情况下,发起HTTP和HTTPS请求并没有任何异同。但有时候会出现一些特殊的问题,就需要我们自己动手解决:
系统过于老旧,没有安装根证书。缺乏根证书的公钥,那么无法验证服务器证书是否安全。
自签名证书。自己的app访问自己的服务器,有时候为了节约经费,可以自己给自己的服务器签名。
证书信息缺乏关键信息,如颁发证书的机构。
对于上面的问题,我们可以自己重写证书验证流程,或者在okHttp中添加信任的服务器公钥,可以解决上面的问题。
最后HTTPS要解决的就是计算机网络中的安全问题,不同问题的解决方法要清楚:
防止消息监听:加密
防止消息篡改:hash算法
验证身份:数字证书
HTTPS就是利用这些方法,为通信双方建立安全连接,从而来实现安全通信。
如果文章对你有帮助,还希望可以留下您的点赞鼓励一下作者~
全文到此,原创不易,觉得有帮助可以点赞收藏评论转发。
有任何想法欢迎评论区交流指正。
如需转载请评论区或私信告知。
另外欢迎光临笔者的个人博客:传送门