是否可以从 HTTP 客户端获取 TLS 机密来解密我自己的 HTTPS 会话?



我正在构建一个像代理一样的网站记录器,以便持续测试网络爬虫。它被分成三个Docker容器,全部在GNU/Linux上:(1)一个代理,(2)一个API和请求队列,以及(3)一个简单的Web应用程序。

它适用于HTTP站点:我单击Web应用程序中的按钮,这会向API容器发出请求,并向内部请求队列添加一些内容,然后通过代理请求站点。代理在站点通过时记录站点。

但是,我忘记了不能记录HTTPS站点流量,现在我已经来实现了这一点,我发现代理只是使用CONNECT动词,然后充当客户端和目标之间的数据交换器。我相信我不能重放相同的数据块,因为加密的一部分使用随机的、一次性的对称密钥(但是我有一个适合测试它的脚本,所以我这样做只是为了教育价值!

所以,我想知道我的获取客户端是否可以放弃足够的机密让代理系统解码字节流?我正在使用Wget进行获取,我想将使用OpenSSL。不过,它不需要是Wget:如果我使用带有流上下文file_get_contents的PHP脚本,我可以向openssl模块询问解密密钥吗?

(公平地说,即使有可能,我可能不会以这种方式解决问题,我只是认为更多地了解TLS会很有趣。在实践中,我将针对代理中的所有安全网站记录一个"null"条目,并要求请求服务通过 API 调用通知代理标头/正文数据,以便以后可以播放。他们当然会有这些项目的明文副本)。

是的,我认为您在这里有几个选择。

HTTPS专门设计用于阻止"中间人"攻击和窃听者,这本质上是您想要实现的目标。不过,你可以打破它的一些假设,并击败它。

在 SSL 连接开始时,1. 远程服务器提供其公钥和证书,2. 客户端验证证书,3. 发送使用服务器公钥加密的会话密钥。有关更多详细信息,请参阅例如 SSL 或 TLS 握手概述

在您描述的场景中,有两种可能的方法可以规避此保护:

1. 重写 TLS 数据,将服务器的证书和密钥替换为您自己的证书和密钥

由于您控制通信通道,因此您可以在步骤(1)中将服务器的公钥和证书替换为您控制的公钥和证书。如果随后要求客户端使用--no-check-certificate参数跳过步骤 (2) 来wget,则可以完全访问加密数据。

这就是 Fiddler 调试代理允许访问 HTTPS 流量的方式,请参阅 https://www.fiddlerbook.com/fiddler/help/httpsdecryption.asp

2. 从客户端应用程序检索会话密钥

由于客户端应用知道会话密钥,因此如果可以提取它,则可以解密流。我想这就是你在问题中的想法。

wget本身没有允许记录会话密钥的选项(请参阅"HTTPS (SSL/TLS) 选项"),但它确实看起来像它的 TLS 库,"GnuTLS"有一个调试选项可以做你想要的,请参阅 GnuTLS 文档中的"调试和审核":

SSLKEYLOGFILE当设置为文件名时,GnuTLS 将以 NSS 密钥日志格式附加会话密钥。该格式可以由wireshark读取,并允许解密会话以进行调试。

尝试将SSLKEYLOGFILE环境变量设置为文件名,看看wget是否会将您的 TLS 会话密钥记录到该文件?您可能需要使用GnuTLS的调试版本重新编译wget。我自己还没有尝试过。

最新更新