都在谈论的 HTTPS,究竟它是如何保护数据传输安全的呢? HTTPS 的应用越来越多,也被大家更多的提及,关于它的运作机制,和大家聊一聊。
HTTPS
随着互联网整体的发展, HTTPS 也被越来越多的应用。 甚至苹果去年还曾经放言要强制所有的 APP 都使用 HTTPS,可见在如今的互联网它的重要性。
那么问题来了,为什么这么多大公司都在积极推进 HTTPS 呢,它和我们平时更多使用的 HTTP 协议究竟有什么区别呢? 我用最简单的话语跟大家聊一聊。
HTTP 明文传输
先从 HTTP 说起,我们过去使用的 HTTP 协议,最大的问题就是,它是明文传输的。因为当时的互联网还只是简单的信息发布,所以明文传输在那个时代并没有太大问题。但随着网络应用越来越复杂,简单的明文传输所带来的问题就显现出来了。
其中一个最突出的问题就是信息劫持。什么叫做劫持呢?简单来说,以我们现在所使用的互联网架构,在发送和接受一条网络请求时,并不是直接发送到目标主机的,而是要经过中间很多个路由器,才能到达主机。
因为 HTTP 是明文传输的,那么所有中间经过的路由器都可以看到你的信息,还可以修改你的信息。假如你请求一个网站,网站的主机给你返回它的主页,一段 HTML 信息:
Hello world.
网站服务器发回给用户的这个信息不是直接到达他机器的,在这中间要经过很多路由器,如果中途经过的某个路由器使坏,对这条信息做了修改, 然后把修改后的内容转发给下一个路由器:
Hello world.这是一条广告
比如像上面这样,最终传输到用户设备上的主页就被恶意加入了一条广告。 而这一切,对用户来说是毫无感知的,这就是信息劫持的一个例子。像这种注入广告还算比较轻微的。如果更严重的甚至会窃取你的个人信息。
HTTPS 如何解决
既然说明了 HTTP 的这个问题,那么我们就再来看看 HTTPS 是如何解决这个问题的。由于篇幅原因,我们只用最简单的语言描述,背后的原理和机制如果都讲清楚就需要比较大的篇幅了。
如果让我们来想,保证信息传输不被恶意篡改的话,会用什么方法呢? 最容易想到的应该就是对信息进行加密后再传输了。其实 HTTPS 也是基于这个原理的, 只是机制更加完善。
先来从加密说起,常用的加密算法有对称加密和非对称加密。对称加密就是用一个秘钥,进行加密和解密。 非对称加密就是加密的时候用一个秘钥,解密的时候用另一个秘钥。
从我这个描述上来看,是不是非对称加密会更安全一些呢? 那为什么还会有对称加密的存在呢? 因为性能。非对称加密要比对称加密更加消耗计算性能。
使用加密算法可以加强传输过程的安全性,但单纯的加密还是不够的。为什么这么说呢,如果你开发的是一个 APP 客户端,这样的设计勉强够用,在你的服务器和客户端上面用同样的秘钥对信息加密和解密就可以让传输安全得到很大的提升。但你要保护好你的秘钥,不被泄露。
但如果你开发的是一个 Web 程序,那这种机制几乎就没办法使用了。因为访问你服务的是浏览器,而不是受你控制的客户端。你没有办法让一个通用浏览器来适配你服务器的特殊加密规则。所以这时候就需要一个更加标准化的传输加密协议,也就是 HTTPS 了。
HTTPS 实现原理
HTTPS 相比于普通的加密传输,最根本的区别就是用于加密传输内容的秘钥是随机的。但 HTTPS 是怎么做到的呢? 总部能把秘钥直接发送给对方吧,因为只要发送,就可能被中间路由器截获。秘钥如果被截获,整个加密算法也就没有意义了。
HTTPS 使用了更聪明的做法,引入了一个叫做数字证书的机制。简单来说,每个支持 HTTPS 的服务端,都会申请一个 SSL 证书。这个证书一般是从专业的证书颁发机构申请。
我们平时方位 HTTPS 网站的时候,浏览器地址栏一般会出现一个小锁头,点击这个小锁头就可以查看证书信息, 我们来看 google 的证书:
它的证书颁发机构是 GeoTrust。 为什么一定要从这些颁发机构申请证书呢? 原因是 HTTPS 的证书链校验机制。比如我们请求 google 的网站,它会先把证书信息发给我们的客户端。 然后我们客户端会做一个叫做证书链校验的操作。
所谓证书链校验,其实就是这样,每个证书都包含一个数字签名,用这个数字签名经过一系列算法,就可以匹配到上一级证书的签名,按照这个算法一直往上延伸,就可以匹配到最顶层证书的签名。就像上面 google 那个证书的截图一样,证书是一级一级的树形结构。
匹配到最顶层证书有什么用呢? 答案是我们的客户端会预置这些顶层证书,比如打开你的 mac 电脑的钥匙串程序,你会看到这样的内容:
我们平时使用的设备都会预置这些证书颁发机构的根证书。还回到前面讨论的证书校验的讨论,当逐级网上找到根证书后,就会和我们预置的这些证书进行匹配,如果能找到相同的,就代表网站发给我们的证书是可信的。否则这个网站就不可信。
这就解释了为什么我们需要从证书颁发机构申请证书了,因为只有证书颁发机构才可以生成它们根证书下面的子证书,生成子证书需要私钥,只有证书颁发机构才有自己的私钥。
说了这么多证书,到底数字证书有什么用呢? 它的作用其中一个是标识网站的身份,这个我们稍后会再详细介绍。
交换秘钥
如果证书验证通过了,就会开始一个交换秘钥的过程。 服务端发给客户端的证书,除了包含上述的验证信息,还包含了证书的公钥。 客户端验证证书有效后,就会发送给服务端一条消息,表明当前客户端可以接受的加密算法等信息,这条信息使用证书给我们的公钥加密传输。
服务端接收到这条消息后,因为它拥有证书的私钥,所以它可以用私钥将信息解密出来。因为私钥不会传输,所以只要不发生其他方式的泄露,理论上只有服务端才可能对这条消息解密。 保证了这条消息的安全性。
服务端知道客户端可以接受哪些加密算法后,就会生成一个针对这些算法的对称秘钥,是的,对称秘钥。然后再用自己的私钥把对称秘钥加密后返回给客户端。
同样,客户端得到这条消息,还会用之前收到的证书公钥再解密,得到这个对称秘钥。 到此为止 HTTPS 的握手过程就完成了。
接下来,客户端就可以用这个对称秘钥给服务端发送消息了。
流程梳理
上面说了这么多,大家或许会有疑惑,再一起梳理一下。 HTTPS 在交换证书和秘钥信息的时候,使用的是非对称加密。 而在真正的信息传输时,使用的是对称加密。
为什么在传输信息时使用对称加密呢,主要还是性能考虑。对于客户端来说对请求信息进行加解密的开销还是有限的。但如果到了服务端,着他机器要对它处理的所有请求都进行加解密,就会造成很大的性能开销了。
这也是为什么都说 HTTPS 的性能要比 HTTP 消耗大的原因了。它额外处理大量的加密和解密的工作。
HTTPS 是如何防止中间路由器劫持的呢? 首先就是证书,因为证书的私钥是不会传输的,所以理论上只有服务端自己才会知道私钥。只要这个私钥不被泄露,那么其他的中间人就不可能解密信息。
证书交换的过程无法被解密,那么对称秘钥在传输过程中就不会被破解。所以在传输信息的时候就可以保证信息的安全了。
当然, HTTPS 并不是绝对安全的。比如我们上面说的,如果服务端自己的证书私钥被泄露了,那么中间路由器就可以解密你们秘钥交换时的信息,就可以破解加密传输了。
更严重的是,根证书的秘钥被泄露。 根证书的秘钥都是保存在证书颁发机构手中。如果这些秘钥被泄露,就可以用它们随意签发合法的子证书,这样中间路由器就可以根本不用转发你的请求,直接返回给你任何恶意信息,而这时候你完全感知不到。
根证书秘钥泄露的事情在现实中确实发生过,所以大家选一个靠谱的证书签发机构,也是保护自己信息传输安全的必备行动。关于 HTTPS 就跟大家聊这么多,我这里说的肯定不是最详细的,但如果你从未了解过这些机制,应该会对你有些用处。