
👨💻程序员三明治 :个人主页
🔥 个人专栏 : 《设计模式精解》 《重学数据结构》
🤞先做到 再看见!
在实际应用中,我们可能会遇到这样的情况:当客户端通过浏览器向服务端发起 HTTPS 请求时,请求被"假基站"劫持并转发至"中间人服务器"。于是,客户端实际上是与中间人完成了 TLS 握手,而中间人再与真正的服务端建立 TLS 连接。具体流程如下:
具体过程如下:
- 客户端发起 HTTPS 连接请求,被假基站重定向至中间人服务器。中间人随后向真实服务端发起 HTTPS 请求。此时,客户端与中间人进行 TLS 握手,中间人同时与服务端完成 TLS 握手。
- 在客户端与中间人的 TLS 握手过程中,中间人向客户端发送其伪造的公钥证书。客户端验证证书合法性,提取公钥并生成随机数,使用该公钥加密后发送给中间人。中间人利用私钥解密获得随机数,双方据此生成对称加密密钥(密钥 A),后续通信均使用该密钥加密。
- 在中间人与服务端的 TLS 握手过程中,服务端发送由 CA 签发的合法证书。中间人提取公钥后生成随机数,加密后发送至服务端。服务端使用私钥解密获得随机数,双方生成对称加密密钥(密钥 B),用于后续通信。
- 通信过程中,中间人使用密钥 A 解密客户端发来的请求数据,再使用密钥 B 重新加密后转发给服务端。服务端返回响应时,中间人用密钥 B 解密,再用密钥 A 加密后传回客户端。
从客户端的视角来看,整个通信过程似乎是直接与服务端进行的,无法察觉中间人的存在。因此,中间人能够解密并查看所有经手的 HTTPS 请求与响应数据,实现"偷看"甚至篡改。
然而,这种攻击方式并非无懈可击,其成功需依赖一个重要前提:用户必须手动接受中间人服务器的伪造证书。
在 TLS 握手阶段,浏览器会识别出伪造证书的非法性,并弹出安全警告提示用户。如果用户忽略警告,执意选择"继续浏览",则相当于主动信任该伪造证书,后续通信内容便会遭到中间人监听。
严格来说,这并不能归咎于 HTTPS 协议本身的安全性不足。浏览器已明确提示风险,用户若坚持访问,则责任不在协议,而在于用户的操作。
此外,若用户的计算机感染恶意软件,被强制安装中间人的根证书,系统中会默认信任该伪造证书。在这种情况下,浏览器不会弹出任何证书警告,HTTPS 通信同样会遭到监听。但这本质上是终端设备被入侵导致的安全问题,而非 HTTPS 协议存在漏洞。
综上所述,HTTPS 协议本身目前并未发现设计层面的漏洞。中间人攻击之所以能够成功,往往是利用了客户端的弱点------例如用户忽略证书警告,或系统被恶意植入根证书。如果用户执意点击「继续浏览此网站」,相当于用户接受了中间人伪造的证书,那么后续整个 HTTPS 通信都能被中间人监听了。
所以,这其实并不能说 HTTPS 不够安全,毕竟浏览器都已经提示证书有问题了,如果用户坚决要访问,那不能怪 HTTPS ,得怪自己手贱。
另外,如果你的电脑中毒了,被恶意导入了中间人的根证书,那么在验证中间人的证书的时候,由于你操作系统信任了中间人的根证书,那么等同于中间人的证书是合法的,这种情况下,浏览器是不会弹出证书存在问题的风险提醒的。
这其实也不关 HTTPS 的事情,是你电脑中毒了才导致 HTTPS 数据被中间人劫持的。
所以,HTTPS 协议本身到目前为止还是没有任何漏洞的,即使你成功进行中间人攻击,本质上是利用了客户端的漏洞(用户点击继续访问或者被恶意导入伪造的根证书),并不是 HTTPS 不够安全。
为什么抓包工具能截取 HTTPS 数据?
很多抓包工具 之所以可以明文看到 HTTPS 数据,工作原理与中间人一致的。
诸如 Fiddler、Charles 等抓包工具能够解密 HTTPS 流量的原理,与上述中间人攻击基本一致。抓包工具要成功代理 HTTPS 通信,需满足以下两个条件:
- 中间人,作为客户端与真实服务端建立连接这一步不会有问题,因为服务端不会校验客户端的身份;
- 中间人,作为服务端与真实客户端建立连接,这里会有客户端信任服务端的问题,也就是服务端必须有对应域名的私钥;
获取私钥的途径通常包括:
- 直接获取服务端私钥(实际不可行);
- 从 CA 机构申请签发该域名的证书(不可行);
- 自行签发证书,并使其被客户端信任。
显然,抓包工具采用的是第三种方式:在客户端安装其自签名的根证书,使系统信任该证书颁发机构(CA)。此后,抓包工具签发的任何证书都会被浏览器视为合法,中间人身份得以成功伪装。
使用抓包工具进行 HTTPS 抓包的时候,需要在客户端安装 Fiddler 的根证书,这里实际上起认证中心(CA)的作用。
如何避免被中间人抓取数据?
我们要保证自己电脑的安全,不要被病毒乘虚而入,而且也不要点击任何证书非法的网站,这样 HTTPS 数据就不会被中间人截取到了。
当然,我们还可以通过 HTTPS 双向认证来避免这种问题。
一般我们的 HTTPS 是单向认证,客户端只会验证了服务端的身份,但是服务端并不会验证客户端的身份。
如果用了双向认证方式,不仅客户端会验证服务端的身份,而且服务端也会验证客户端的身份。服务端一旦验证到请求自己的客户端为不可信任的,服务端就拒绝继续通信,客户端如果发现服务端为不可信任的,那么也中止通信。
如果我的内容对你有帮助,请辛苦动动您的手指为我点赞,评论,收藏。感谢大家!!