HTTPS和SSL/TLS协议是如何保证数据传输的安全性的

       基于上篇提到的问题(Android5.0以下手机通过https请求服务器报SSLException异常的原因及解决方案) 事后我又深入的研究了下SSL/TLS协议。然后这篇就介绍一下HTTPS和SSL/TLS协议是如何保证数据传输的安全性的。

咱们通常所说的 HTTPS 协议,就是指安全套接字层超文本传输协议HTTPS。就是“HTTP 协议”和“SSL/TLS 协议”的组合,你可以把 HTTPS 大致理解为——“HTTP over SSL”或“HTTP over TLS”。HTTP协议以明文方式发送内容,不提供任何方式的数据加密,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。

加密分为“对称加密”和“非对称加密”两种:

对称加密:所谓的“对称加密”,意思就是说:“加密”和“解密”使用相同的密钥。

非对称加密::所谓的“非对称加密”,意思就是说:“加密”和“解密”使用不同的密钥。

单纯用“对称加密算法”:

如果用对称加密,浏览器和服务器之间势必先要交换“对称加密的密钥”,如果这个密钥直接用明文传输,很容易就会被第三方(有可能是“攻击者”)偷窥到;如果这个密钥用密文传输,那就再次引入了“如何交换加密密钥”的问题,这就造成了无限循环,所以,单纯用对称加密,是没有作用的。

单纯用“非对称加密算法”:

上面已经说了“非对称加密”的特点——“加密和解密采用不同的密钥”。基于这个特点,可以避开前面提到的“循环逻辑”的困境。大致的步骤如下:

第1步 
网站服务器先基于“非对称加密算法”,随机生成一个“密钥对”(为叙述方便,称之为“k1 和 k2”)。因为是随机生成的,目前为止,只有网站服务器才知道 k1 和 k2。

第2步 
网站把 k1 保留在自己手中,把 k2 用【明文】的方式发送给访问者的浏览器。 
因为 k2 是明文发送的,自然有可能被偷窥。不过不要紧。即使偷窥者拿到 k2,也【很难】根据 k2 推算出 k1 
(这一点是由“非对称加密算法”从数学上保证的)。

第3步 
浏览器拿到 k2 之后,先【随机生成】第三个对称加密的密钥(简称 k)。 
然后用 k2 加密 k,得到 k’(k’ 是 k 的加密结果) 
浏览器把 k’ 发送给网站服务器。

由于 k1 和 k2 是成对的,所以只有 k1 才能解密 k2 的加密结果。 
因此这个过程中,即使被第三方偷窥,第三方也【无法】从 k’ 解密得到 k

第4步 
网站服务器拿到 k’ 之后,用 k1 进行解密,得到 k 
至此,浏览器和网站服务器就完成了密钥交换,双方都知道 k,而且【貌似】第三方无法拿到 k 
然后,双方就可以用 k 来进行数据双向传输的加密。

然后上面的方案依然是不安全的——虽然可以在一定程度上防止网络数据的【偷窥/嗅探】,但是无法防范网络数据的【篡改】。

假设有一个攻击者处于“浏览器”和“网站服务器”的通讯线路之间,并且这个攻击者具备“篡改双方传输数据”的能力。那么,这个攻击者就可以攻破上述方案,具体的攻击过程如下:

第1步 
这一步跟原先一样——服务器先随机生成一个“非对称的密钥对”k1 和 k2(此时只有网站知道 k1 和 k2)

第2步 
当网站发送 k2 给浏览器的时候,攻击者截获 k2,保留在自己手上。 
然后攻击者自己生成一个【伪造的】密钥对(以下称为 pk1 和 pk2)。 
攻击者把 pk2 发送给浏览器。

第3步 
浏览器收到 pk2,以为 pk2 就是网站发送的。 
浏览器不知情,依旧随机生成一个对称加密的密钥 k,然后用 pk2 加密 k,得到密文的 k’ 
浏览器把 k’ 发送给网站。 
(以下是关键) 
发送的过程中,再次被攻击者截获。 
因为 pk1 pk2 都是攻击者自己生成的,所以攻击者自然就可以用 pk1 来解密 k’ 得到 k 
然后,攻击者拿到 k 之后,用之前截获的 k2 重新加密,得到 k”,并把 k” 发送给网站。

第4步 
网站服务器收到了 k” 之后,用自己保存的 k1 可以正常解密,所以网站方面不会起疑心。 
至此,攻击者完成了一次漂亮的偷梁换柱,而且让双方都没有起疑心。

上述过程,也就是传说中大名鼎鼎的“中间人攻击”。洋文叫做“Man-In-The-Middle attack”。缩写是 MITM。

因为“缺乏身份认证机制”,所以当攻击者一开始截获 k2 并把自己伪造的 pk2 发送给浏览器时,浏览器无法鉴别:自己收到的密钥是不是真的来自于网站服务器,假如具备某种【可靠的】身份认证机制,即使攻击者能够篡改数据,但是篡改之后的数据很容易被识破。那篡改也就失去了意义。

基于CA证书的秘钥交换

第1步(这是“一次性”的准备工作) 
网站方面首先要花一笔银子,在某个 CA 那里购买一个数字证书。 
该证书通常会对应几个文件:其中一个文件包含公钥,还有一个文件包含私钥。 
此处的“私钥”,相当于“方案2”里面的 k1;而“公钥”类似于“方案2”里面的 k2。 
网站方面必须在 Web 服务器上部署这两个文件。

所谓的“公钥”,顾名思义就是可以公开的 key;而所谓的“私钥”就是私密的 key。 
其实前面已经说过了,这里再唠叨一下:

“非对称加密算法”从数学上确保了——即使你知道某个公钥,也很难(不是不可能,是很难)根据此公钥推导出对应的私钥。

第2步 
当浏览器访问该网站,Web 服务器首先把包含公钥的证书发送给浏览器。

第3步 
浏览器验证网站发过来的证书。如果发现其中有诈,浏览器会提示“CA 证书安全警告”。 
由于有了这一步,就大大降低了(注意:是“大大降低”,而不是“彻底消除”)前面提到的“中间人攻击”的风险。

为啥浏览器能发现 CA 证书是否有诈? 
因为正经的 CA 证书,都是来自某个权威的 CA。如果某个 CA 足够权威,那么主流的操作系统(或浏览器)会内置该 CA 的“根证书”。(比如 Windows 中就内置了几十个权威 CA 的根证书) 
因此,浏览器就可以利用系统内置的根证书,来判断网站发过来的 CA 证书是不是某个 CA 颁发的。 

第4步 
如果网站发过来的 CA 证书没有问题,那么浏览器就从该 CA 证书中提取出“公钥”。 
然后浏览器随机生成一个“对称加密的密钥”(以下称为 k)。用 CA 证书的公钥加密 k,得到密文 k’ 
浏览器把 k’ 发送给网站。

第5步 
网站收到浏览器发过来的 k’,用服务器上的私钥进行解密,得到 k。 
至此,浏览器和网站都拥有 k,“密钥交换”大功告成啦。

这种方案从理论上讲没有明显的漏洞,目前的 SSL/TLS 大致采用的就是这个方案。

 

 

 

 

 

 

你可能感兴趣的:(Android开发)