https://www.zhihu.com/people/bei-ji-85/posts
背景
前一段时间,公司北京地区上线了一个HTTPS防火墙,用来监听HTTPS流量。防火墙上线之前,邮件通知给管理层,我从我老大那里听说这个事情的时候,说这个有风险,然后意外地发现,很多人原来都不知道HTTPS防火墙的安全风险,甚至很多搞网络的人也不清楚。
HTTPS防火墙,本质上就是一种中间人攻击,这个概念是我大学的时候网络老师提到的一个概念,我只有毕业头两年做过一些路由协议相关的工作,所以了解一个大概。不仅如此,很多涉及安全的领域从业者,也不是太清楚“随便信任一个证书”的安全风险,最直接的风险,比特币的钱包可能会失窃。
HTTPS通信原理
HTTPS本质上就是要对HTTP通信内容进行加密。通信加密的需要解决最根本的两个问题是:
问题1:如何确定加密算法以及密码?
问题2:如何保证密码不被窃听?
通常来说,密码应该由服务器和客户端使用随机的方式生成(可以解决问题1),但这样会引发新问题(问题2):如何把这个随机数通告给对方?如果密码(密钥)用明文传输,那么必然存在着在中间节点被窃听的可能性。所以,密码(密钥)必然是要以加密的方式传输的。但有什么办法既可以加密,又能保证对方可以正确收到?
这里就需要使用非对称加密技术了:非对称加密最常见的就是RSA算法,RSA算法是基于素数分解的难点:两个大素数相乘十分容易,但对乘积进行因式分解却非常困难。比如79032091要分解肯定没办法手算,需要借助计算机8887*8893,但如果两个素数非常巨大(比如256位),那么要想分解就非常困难了。
RSA算法利用了类似的技术,提供了两套密钥,公钥和私钥,二者并不相同,公钥用于加密,私钥用于解密。即使有中间人获得了公钥,仍然无法破解,因为公钥只能加密,不能解密。公钥可以公开给所有人使用,只要保存好私钥即可。
比如在浏览器里使用HTTPS方式访问百度,大概的交互流程就是(原理介绍,并非实际情况):
客户端用百度的公钥去加密一个自己生成的随机数作为后续交互密码。
百度收到了这个加密的密文,并用百度的私钥解密了内容,获得后续交互密码,然后用这个交互密码进行后续操作。
之后二者之间就可以互相用最初生成的随机数作为密码进行通信。因为它是随机的,并且用非对称加密,中间人即使拦截也无法解开其中的内容,这样就保证了安全。至少这么设计是安全的。
但是,这个交互过程有一个漏洞,就是网站的公钥如何获得?有人会说,那让浏览器自己去访问百度,然后获取公钥不就可以了吗?那么,如何保证浏览器拿到的公钥就是百度的公钥呢?如何保证这个公钥不是一个中间人的公钥的?
这就是中间人攻击的工作方式(之一):
1. 客户端询问百度的公钥。
2. 查询请求被中间人拦截,伪造了百度的公钥,换成中间人的公钥,比如中间人是知乎,那么就是知乎的公钥,同时中间人也持有对应的私钥(知乎的私钥)。
之后客户端的一切通信,在中间人(知乎)那里都会被中间人的私钥(知乎的私钥)给解开内容,因为中间人通过替换的中间人公钥以及对应的中间人私钥解开了交互密码。
HTTPS协议设计的过程中,考虑到了这种情况,所以对于获取的公钥的过程做了一个验证,就是证书验证机制。
比如访问百度的时候,浏览器地址栏那里,是有一个小锁头的图标,点开可以看到证书信息:
证书的原理相当于对网站下发的公钥做一次哈希校验,然后与本机预先存储的证书信息做验证,如果一致,说明对方的公钥是可信的。
这里,仍然有一个问题:本机预先存储——这个怎么来?这个时候,就需要“证书颁发机构”了。
证书颁发机构,本质上是一个收钱的机构(狗头),收钱,然后颁发一个可信的证书给网站,同时,操作系统厂商(Windows、Linux、MacOS)信任“证书颁发机构”颁发的证书,在浏览器或者操作系统里默认集成了这些机构的根证书,这样就保证了证书是可信可靠的。每个证书都是有有效期的,如果有网站恶意使用了证书,那么“证书颁发机构”就会吊销对应的证书,之后浏览器再访问这些网站的时候,如果网站证书校验不通过,那么浏览器地址栏里的小锁头就不见了,取而代之的是一个浏览警告:
上图就是百度被中间人攻击的状态。
即使忽略警告,后续浏览也会有各种提示:
这种情况可能是:1. 你的浏览器到百度网站之间的通信发生了中间人攻击;2. 百度这个网站的证书被吊销了。通常情况下,此时你的浏览器访问将不再安全。
正常的证书包含一系列的验证信息(通过点开浏览器的小锁头查看详细信息):
非法的证书:
查看本机的信任的根证书的办法是运行certmgr.msc,在左侧栏点开(中文貌似是受信任的根证书颁发机构)即可查看到:
右侧红框的GlobalSign就是百度的证书的颁发机构。
这样,通过操作系统预装的信任的“证书颁发机构”加上HTTPS交互过程中的非对称加密技术,就保证了整个通信流程都是被加密且不被第三方窃听的。
HTTPS防火墙工作原理
如果按照这种方式,那么HTTPS防火墙是不可能截获客户端到服务器之间的通信内容的。所以HTTPS防火墙要做的一件事就是,强制安装一个证书到“受信任”列表中(也就是上图我涂黑的那两个证书,就是HTTPS防火墙为了能够工作,强制IT部门安装到每个公司的PC上的)。有了这个“受信任”证书,HTTPS防火墙,也就是中间人,即可把任何想要监听的网站的证书,都替换成这个“受信任”证书,之后通过HTTPS防火墙内置的私钥,解开客户端到服务器之间的全部加密通信。
这种方式是有很大的安全风险的,因为,如果HTTPS防火墙本身被攻击,私钥泄漏,那么在公司上网将不再安全,所有HTTPS网页上的密码,都可能有泄漏的危险,比如知乎、微博等网站,仅仅依靠HTTPS加密来保证登录密码的安全,这些密码都不再安全。
后续
HTTPS防火墙准备在北美上线的时候,终于被公司的技术大佬发现问题了,被CTO叫停,但北京地区的HTTPS防火墙至今仍然运行,也许这就是所谓的中国人没有隐私吧。
另外,听说不少互联网公司都有这个,所以在公司登陆网站的时候,还是要注意一下账号密码安全,别轻易使用公司的WiFi,如果使用公司的网络和硬件,需要注意保护好用户名密码等信息。
其它
通过上图可以看到,HTTPS防火墙需要模拟真实的HTTPS请求,这里有一个问题,就是如果请求量巨大的话,工作负载会很重,需要缓存大量的请求中间状态(相当于自己变成一个网站服务器),所以对于大公司来说,HTTPS防火墙如果一直监听,那么对访问外网影响很大。我们公司这个防火墙上线之初,经常会因为访问量问题瘫痪,可见它非常脆弱。
一些网站,以及一些APP会在客户端做二次校验,校验不通过的话是无法登陆的,这种会避免密码泄露(点名:网易邮箱网页版)。
通常来说能同时掌握证书+网关硬件,才能做到完整的中间人攻击,一般来说,只有在公司(电脑+网络都属于公司)的情况下才能做到。或者,是国家级的行为,然后把中间人部署到ISP的网关上。当然,国家级的行为,也没必要这么费劲,有其它(物理)办法就是了。
截图来自firefox,操作系统是WINXP(虚拟机,在真实的部署了HTTPS防火墙环境里),WIN10(带HTTPS防火墙,信任证书),WIN7(外网)。