HttpListenerRequest.GetClientCertificate() 未返回完整的证书链

HttpListenerRequest.GetClientCertificate() not returning the complete certificate chain

我有一个使用 HttpListener in C#, there is a Go client which talks to this server. As part of the requirement I need to validate the certificates sent from the client on the server and I'm sending a certificate chain from the client. I found the method HttpListenerRequest.GetClientCertificate() 实现的网络服务器来获取服务器上的证书,但我只能收到叶证书而不是整个链,这阻碍了我执行链验证。有没有办法使用 HttpListener 作为服务器来接收整个链。

PS:我尝试将相同的证书链发送到 Go 服务器,Go 在 Tls Config 中有 ssl 回调处理程序(VerifyPeerCertificate),我使用它我能够读取整个证书链。我只想用 C# 中现有的 HttpListener 服务器来实现这一点。

编辑: 我的客户端证书是一个链(客户端证书 + 中间 CA + 根 CA)。我将根 CA 预先存储在受信任的根证书颁发机构中。我需要在 Windows Trust Store 中获取中间 CA,以便我可以为客户端证书构建链,因为我无法预先存储中间 CA,所以我的想法是从客户端发送链并提取客户端与服务器对话时的中间 CA。 因为我能够使用具有相同客户端的 Go 服务器接收完整的链,所以我可以确认客户端始终发送链,但不知何故,我们在 C# 中为 HttpListener 提供的方法似乎忽略了链。

通常客户端只是发送其客户端证书,然后服务器负责检查客户端证书是否可信。如果任何人都可以发送带有完整链的客户端证书,则服务器可以接受任何证书颁发机构(包括任何被泄露的证书)。因此,必须在服务器上信任颁发客户端证书的证书颁发机构的证书,以确保该机构是可信的,并且服务器可以请求该机构以确保客户端证书未被吊销。在 Windows 这是通过将证书颁发机构的证书添加到受信任的根证书颁发机构存储来完成的。

HttpListenerRequest.GetClientCertificate() source 只加载一个证书。

在服务器端检查完整链。服务器必须能够连接到已签署客户端证书的 AIA 才能下载中间 CA。

            var chain = new X509Chain();
            chain.ChainPolicy = new X509ChainPolicy()
            {
                DisableCertificateDownloads = false,
                RevocationFlag = X509RevocationFlag.EntireChain,
                RevocationMode = X509RevocationMode.Online,
                UrlRetrievalTimeout = TimeSpan.Zero,
                VerificationFlags = X509VerificationFlags.AllFlags
            };

您可以尝试实现自己的 HttpListenerRequest 并将其用作管道中的中间件。