三种解密 HTTPS 流量的方法介绍

 

转载自:https://imququ.com/post/how-to-decrypt-https.html做者: Jerry Qu
html

Web 安全是一项系统工程,任何细微疏忽均可能致使整个安全壁垒土崩瓦解。拿 HTTPS 来讲,它的「内容加密、数据完整性、身份认证」三大安全保证,也会受到非法根证书、服务端配置错误、SSL 库漏洞、私钥被盗等等风险的影响。不少同窗认为只要访问的网站地址前有一把小绿锁就绝对安全,其实否则。本文经过介绍三种最常规的 HTTPS 流量解密方法及原理,浅谈一下 HTTPS 的安全风险。git

Man-in-the-middle

Man-in-the-middle(中间人,简称为 MITM),可以与网络通信两端分别建立链接,交换其收到的数据,使得通信两端都认为本身直接与对方对话,事实上整个会话都被中间人所控制。简而言之,在真正的服务端看来,中间人是客户端;而真正的客户端会认为中间人是服务端。github

实现中间人攻击有各类各样的手段,这里不展开讨论。一些常见的 HTTP/HTTPS 抓包调试工具,都是经过建立本地 Proxy 服务,再修改浏览器 Proxy 设置来达到拦截流量的目的,他们的工做原理与中间人攻击一致。我用过的这一类工具备:FiddlerCharles 和 whistle。我在「HTTP 代理原理及实现(一)」一文中介绍的 HTTP 普通代理,扮演的就是 HTTP 中间人角色。web

本文主要讨论 HTTPS 中间人,简单示意以下:算法

Server <---> Local Proxy <---> Browser
         ^                 ^
       HTTPS(1)          HTTPS(2)

上述 HTTPS(1) 链接,是中间人冒充客户端,与服务端创建的链接,因为 HTTPS 服务端通常不认证客户端身份,这一步一般没有问题。而对于 HTTPS(2) 链接来讲,中间人想要冒充服务端,必须拥有对应域名的证书私钥,而攻击者要拿到私钥,只能经过这些手段:浏览器

  1. 去网站服务器上拿;
  2. 从 CA 处签发证书;
  3. 本身签发证书。

要防范前两点,须要网站作好各个方面的安全防御,从主机安全到网站安全(避免私钥被盗),从域名解析安全到域名邮箱安全(避免攻击者重签证书)。而攻击者本身签发的证书,没法经过系统内置根证书的验证,默认没法用于中间人攻击。安全

对于 Fiddler 这一类调试工具来讲,可以解密 HTTPS 流量的关键在于他们会往系统受信任的根证书列表导入本身的证书,这样他们的自签证书就能被浏览器信任。进入 Fiddler 设置中的「HTTPS」Tab,勾选相关功能后,就能够顺利解密和修改 HTTPS 流量。这时在浏览器中能够看到这样的证书链:服务器

 

RSA Private Key

我在「使用 Wireshark 调试 HTTP/2 流量」这篇文章中写到:Wireshark 的抓包原理是直接读取并分析网卡数据,要想让它解密 HTTPS 流量,有两个办法:网络

  1. 若是你拥有 HTTPS 网站的加密私钥,能够用来解密这个网站的加密流量;
  2. 某些浏览器支持将 TLS 会话中使用的对称密钥保存在外部文件中,可供 Wireshark 加密使用。

那篇文章介绍了第二种方案,本文简单介绍第一种。dom

打开 Wireshark 的 SSL 协议设置,参考下图,把 IP、端口、协议和证书私钥都配上(私钥必须存为 PEM 格式):

而后访问私钥对应的网站,能够看到流量已被解密:

截图中的加密数据是以 HTTP/1 传输的,这种方式能解密 HTTP/2 流量吗?结论是:不能!具体缘由下面慢慢分析。

咱们知道,TLS 握手阶段须要进行密钥交换和服务端认证这两个重要的操做,密钥交换是为了在不安全数据通道中产生一个只有通讯双方知道的共享密钥 Premaster Secret,进而生成 Master Secret 以及后续对称加密 Session Key 和 MAC Key。而客户端进行服务端认证的目的是确保链接到拥有网站私钥的合法服务器。

最多见的密钥交换方式是 RSA,下面这张图清晰的描述了这个过程:

Client Random 和 Server Random 明文传输,中间人能够直接查看。客户端生成 Premaster Secret 后,用服务端证书公钥加密后发送,若是服务端拥有对应的私钥,就能够成功解密获得 Premaster Secret。这时,客户端和服务端拥有相同的 Client Random、Server Random 和 Premaster Secret,能够各自算出相同的后续所需 Key。

能够看到,这种方式合并了密钥交换和服务端认证两个步骤,若是服务端能解密 Premaster Secret,也就意味着服务端拥有正确的私钥。中间人没有私钥,没法获得 Premaster Secret,也就没法解密后续流量。

对于 Wireshark 来讲,配置某个网站的私钥后,能解密这个网站「使用 RSA 进行密钥交换」的加密流量就很容易理解了。

显然,RSA 密钥交换有一个很大的问题:没有前向安全性Forward Secrecy。这意味着攻击者能够把监听到的加密流量先存起来,后续一旦拿到了私钥,以前全部流量均可以成功解密。

实际上,目前大部分 HTTPS 流量用的都是 ECDHE 密钥交换。ECDHE 是使用椭圆曲线(ECC)的 DH(Diffie-Hellman)算法。下图是 DH 密钥交换过程:

上图中的 Server DH Parameter 是用证书私钥签名的,客户端使用证书公钥就能够验证服务端合法性。相比 RSA 密钥交换,DH 由传递 Premaster Scret 变成了传递 DH 算法所需的 Parameter,而后双方各自算出 Premaster Secret。

对于这种状况,因为 Premaster Secret 无需交换,中间人就算有私钥也没法得到 Premaster Secret 和 Master Secret。也就是说 Wireshark 没法经过配置 RSA Private Key 的方式解密「使用 ECDHE 进行密钥交换」的加密流量。固然,使用 ECDHE 后,虽然中间人拿到私钥也没法解密以前的流量,但他能够实施 MITM 攻击来解密以后的流量,因此私钥仍是要保管好。

相比 RSA 既能够用于密钥交换,又能够用于数字签名;ECC 这边就分得比较清楚了:ECDHE 用于密钥交换,ECDSA 用于数字签名。也就是目前密钥交换 + 签名有三种主流选择:

  • RSA 密钥交换、RSA 数字签名;
  • ECDHE 密钥交换、RSA 数字签名;
  • ECDHE 密钥交换、ECDSA 数字签名;

如下是使用这三种密钥交换方式的网站在 Chrome 中的截图:

key exchange

key exchange

HTTP/2 中只能使用 TLSv1.2+,还禁用了几百种 CipherSuite(详见:TLS 1.2 Cipher Suite Black List)。实际上,HTTP/2 容许使用的 CipherSuite 必须采用具备前向安全性的密钥交换算法,不容许使用 RSA 密钥交换。这也是为何 RSA Private Key 没法解密 HTTP/2 加密流量。

SSLKEYLOGFILE

Firefox 和 Chrome 都会在系统环境变量存在 SSLKEYLOGFILE 文件路径时,将每一个 HTTPS 链接产生的 Premaster Secret 或 Master Secret 存下来。有了这个文件,Wireshark 就能够轻松解密 HTTPS 流量,即便是使用了 ECDHE 这种具备前向安全性的密钥交换,以下图:

decrypt http2 over tls

decrypt http2 over tls

这种方案的详细介绍请参考「使用 Wireshark 调试 HTTP/2 流量」这篇文章。

SSLKEYLOGFILE 文件记录的是 HTTPS 数据传输中最重要的加密信息,若是不是出于调试目的,通常也没人会主动配置这个环境变量,因此这个方案基本不会对 HTTPS 安全性产生影响。

总结

Fiddler 这类工具经过往系统导入根证书来实现 HTTPS 流量解密,充当中间人角色。要防范真正的 HTTPS 中间人攻击,网站方须要保管好本身的证书私钥和域名认证信息,为了防范不良 CA 非法向第三方签发本身的网站证书,还要尽量启用 Certificate TransparencyHTTP Public Key Pinning 等策略;用户方不要随便信任来历不明的证书,更不要随意导入证书到根证书列表,还要养成常常检查经常使用网站证书链的习惯。

RSA 密钥交换没有前向安全性,这意味着一旦私钥泄漏,以前全部加密流量均可以解开。为此,网站方须要启用使用 ECDHE 做为密钥交换的 CipherSuite,或者直接使用 ECC 证书;用户方须要弃用不支持 ECDHE 的古董操做系统及浏览器。

对于浏览器而言,HTTPS 毫无秘密,经过浏览器生成的 SSLKEYLOGFILE 文件,Wireshark 能够轻松解密 HTTPS 流量。另外,若是浏览器被安装恶意扩展,即便访问安全的 HTTPS 网站,提交的数据同样能够被截获。这种客户端被攻击者控制引起的安全问题,没法经过 HTTPS 来解决。

相关文章
相关标签/搜索