Chrome 如何知道在握手中没有发送 "Client Request" 时提供客户端证书?

How does Chrome know to provide Client Certificate when no "Client Request" is sent in handshake?

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

当我的应用程序尝试连接到外部服务器的其余部分时 API - 让我们称之为 https://www.server.com/api/resolve - 我希望“证书请求”握手元素与他们的服务器问候一起发送。据我从我和服务器之间所有流量的 tcpdump 可以看出,它没有发送。仅发送“服务器问候、证书、证书状态、服务器密钥交换、服务器问候完成”:

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

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

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

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

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

或者,wireshark 有没有可能在骗我?当我测试时,例如:https://client.badssl.com/ which requests Mutual SSL, I see the Certificate Request right after the Server Key Exchange exactly as I should. I noticed in the TLSv1.2 RFC (https://www.rfc-editor.org/rfc/rfc5246) 它指出:

"In particular, the certificate and certificate request handshake messages can be large enough to require fragmentation."

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

应用程序数据抓包后,有几个加密握手消息。这很可能意味着服务器本身在默认情况下不请求客户端证书,而是仅针对特定 URL.

请求证书

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