一.背景
1.1 遇到的问题
最近公司的云采编app为了加强数据安全,决定将现有的http协议改为使用https协议。目前此app使用的网络请求还是非常古老的HttpClient,并且,其中有关于https的设置,但是这个设置是骗人的因为里面写的是相信所有的服务端(不校验域名)。那么问题来了怎么使我的https协议真正的起作用呢?下面就是解决问题的过程和过程中关于https的思考和总结。由于涉及的点很多这里打算分几篇记录。
Android中HTTPS之一(一)HTTP和TCP/IP基础
Android中HTTPS之一(二)SSL/TLS协议运行原理
Android中HTTPS之一(三)具体操作(代码实现)
1.2 解决过程中的问题
1.2.1 网上大多数的解决方案都是抄的,而且没有真正用到生产中就瞎写,我感觉这是极度不负责任的表现;
1.2.2 真正要解决问题,要“知其然,知其所以然”,原理比较重要(知道原理才能用的放心);同时怎么写也是很重要的(好多的网上的解决方案都是给了个原理,写到代码里的时候完全不对,例如校验服务端压根就没有写,因为它们压根就没用过,只是瞎写);
1.3真正的问题
1.3.1 https是什么,它比http安全在哪里(涉及https和http概念)?
1.3.2 CA证书是什么?
1.3.3 使用CA机构颁发(购买的)的证书和使用自签名的证书配置时候的区别?更进一步使用CA机构的证书的时候客户端要不要自己写验证过程?
1.3.4 app客户端验证服务端的时候具体要验证什么?
1.3.5 各个网络框架中具体代码怎么写?
1.4着重强调的点
同时注意无论我们使用的公钥证书是否由CA机构颁发,我们都应在客户端配置的时候对服务端的合法性进行校验。
解释:虽然当使用可信CA签发的证书的时候,Android系统会为我们进行合法性校验(表现为只需要调用相应网络框架中的Https相应sdk方法,不用自己动手校验)可以正常访问服务端,但是这里面存在安全漏洞(我公司在实际生产中就遇到过类似的事情,当时请第三方安全公司检验说要做“手动”服务端安全校验)。私有CA签发的数字证书不在Android系统信任证书列表内,所以服务端无法访问,必然需要自己配置了(服务端和客户端都要配置)。
二.涉及的点
根据上面1.3中提出的问题很好总结出我们要的知识点,如下:
2.1 https比http安全的原理
2.2 http概念以及Tcp的握手挥手过程
2.3 https加密过程原理
2.4 CA机构和证书
2.5 https在代码中具体怎么写(这里主要是Httpclient,并且是我自己调通了的;至于HttpsUrlConnection,Okhttp,WebView中的配置和HttpClient原理是一样的,网上有比较完善可用的代码,这里不做拷贝)
2.6 自己如何生成服务端和客户端需要的私钥证书和公钥证书
作为第一篇,本篇主要介绍点如下:
1.https比http安全的原理
2.http和https等各种基本概念的链接
3.Tcp的三次握手和四次挥手
三.Https协议的原理(原理很乏味但很有用,知其然,知其所以然)
3.1 为什么使用https
相对Http来说就是安全。HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。由于在Http(应用层协议)和Tcp(传输层协议)中间增加了SSL(安全套接字层:加密/身份验证作用),在建立连接的时候先Tcp的三次握手然后加入了SSL握手,而后者的握手过程就是安全检测的过程(后面Tcp三次握手和四次挥手;SSL的握手过程都有详细分析),从而带来了安全的链接。
下图可以简单的表示Http和Https的不同
3.2 各种相关概念
下面罗列一些用到的基础概念,具体用来干什么,为什么产生的以及各自的演进过程大家可以点击下面的概念的链接或者自己搜索。
3.2.1 HTTP:超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。
3.2.2 HTTPS:(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。
3.2.3 TCP:(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义
3.2.4 TCP/IP协议:不是TCP和IP这两个协议的合称,而是指因特网整个TCP/IP协议族。
3.2.5 OSI参考模型OSI参考模型:网络参考模型,是ISO的建议,它是为了使各层上的协议国际标准化而发展起来的。
3.2.6 CA认证,第三方权威机构,中间人的角色保障信息安全。
3.3Tcp的三次握手和四次挥手
3.3.1 链接的时候的三次握手
先来了解一下TCP详解,这里面有Tcp的报文结构,SYN,ACK标记是什么意思有什么作用等。如果想仔细研究一下Tcp的报文的话可以参考Tcp报文的英文文档。
3.3.1.1这里简单介绍我们用到的Tcp报文头的部分知识,首先是Tcp的报文头部结构如下图:
这里介绍比较重要的序号和确认号
序号(Sequence Number):32 bits.
The sequence number of the first data byte in this segment. If the SYN bit is set, the sequence number is the initial sequence number and the first data byte is initial sequence number + 1.这是英文注释。
确认序号(Acknowledgment Number). 32 bits.
If the ACK bit is set, this field contains the value of the next sequence number the sender of the segment is expecting to receive. Once a connection is established this is always sent.这是英文注释。
解释一下分段的意义和两个序号的意义:TCP是将应用层交给的数据分段(package)后发送的。为了支持数据出错重发和数据段组装,TCP程序为每个数据段封装的报头中设计了两个数据报序号字段,分别称为发送序号和确认序号。出错重发是指一旦发现有丢失的数据段,可以重发丢失的数据,以保证数据传输的完整性。如果数据没有分段,出错后源主机就不得不重发整个数据。为了确认丢失的是哪个数据段,报文就需要安装序号。另一方面,数据分段可以使报文在网络中的传输非常灵活。一个数据的各个分段,可以选择不同的路径到达目标主机。由于网络中个条路径在传输速度上不一致性,有可能前面发出的数据段后到达,而后发出的数据段先到达。为了使目标主机能够按照正确的次序重新装配数据,也需要在数据段的报头中安装序号。TCP报头中的第三、四字段(seq和ack)是两个基本点序号字段。发送序号是指本数据段是第几号报文包。接收序号是指对方该发来的下一个数据段是第几号段。确认序号实际上是已经接收到的最后一个数据段加1。
3.3.1.2下面是三次握手的过程示意图
下面对上图解释一下:
首先,四个名词的作用:
SYN: SYN置1就表示这是一个连接请求或连接接受报文。ACK : TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1。
seq是序列号,这是为了连接以后传送数据用的,ack是对收到的数据包的确认,值是等待接收的数据包的序列号。(seq是数据包本身的序列号;ack是期望对方继续发送的那个数据包的序列号。
)