首页 > 解决方案 > 当握手中没有发送“客户端请求”时,Chrome 如何知道提供客户端证书?

问题描述

在调查我的客户端应用程序和外部服务器之间的相互 SSL 故障时,这个问题让我感到困惑。

当我的应用程序尝试连接到外部服务器的 REST API 时——我们称之为https://www.server.com/api/resolve——我希望与他们的服务器问候一起发送一个“证书请求”握手元素。据我从我和服务器之间所有流量的 tcpdump 可以看出,它没有被发送。只发送“Server Hello, Certificate, Certificate Status, Server Key Exchange, Server Hello Done”:

TLSv1.2 握手的 tcpdump:https ://i.stack.imgur.com/50Ous.png

但是,当我尝试在 Chrome 中访问相同的 API URL 时,浏览器会显示一个框,要求我选择我的客户端证书以进行相互身份验证。当我捕获该握手的转储直到浏览器提示我输入证书时,我仍然没有看到服务器发送的“证书请求”:

浏览器导航到 API 的 Tcpdump:https ://i.stack.imgur.com/hvOEx.png

在 Chrome 中选择证书后,我被定向到该站点,但是我也没有看到在我的 TLS1.2 捕获中发送的客户端“证书”。

我的问题是,如果 TLS 握手中未发送该请求,Chrome 有什么方法可以知道服务器请求了客户端证书?

或者,是否有可能wireshark 对我撒谎?例如,当我针对请求 Mutual SSL 的https://client.badssl.com/进行测试时,我会在服务器密钥交换之后看到证书请求,就像我应该看到的那样。我在 TLSv1.2 RFC ( https://www.rfc-editor.org/rfc/rfc5246 ) 中注意到:

“特别是,证书和证书请求握手消息可能大到需要分段。”

但这应该与 Wireshark 如何显示 TLS 信息无关。

标签: google-chromesslwiresharktls1.2mutual-authentication

解决方案


在应用数据之后的数据包捕获中有几个Encrypted Handshake Message。这很可能意味着服务器本身默认情况下不请求客户端证书,而是仅针对特定 URL 请求证书。

在这种情况下,首先在没有CertificateRequest的情况下完成 TLS 握手。握手完成后,客户端通过加密连接发送 HTTP 请求,该连接是数据包捕获中的应用程序数据。服务器将确定请求的 URL 需要客户端证书并启动重新协商,即另一个 TLS 握手,但这次是CertificateRequest。但是由于连接已经加密,因此重新协商仅作为加密握手消息可见,并且如果不解密流量就无法看到详细信息。


推荐阅读