HttpWebRequest似乎没有发送客户端SSL证书

Bas*_*sic 7 .net security ssl nginx httpwebrequest

我正在尝试使用a HttpWebRequest来查询运行nginx的远程服务器.我需要提供客户端证书才能完成连接.

我正在做以下事情:

Dim Request As HttpWebRequest = DirectCast(WebRequest.Create(Url), HttpWebRequest)
Dim Cert = SSL.GetClientCertificate()
Request.ClientCertificates.Clear()
Request.ClientCertificates.Add(Cert)
Dim Response As WebResponse = Request.GetResponse()
Run Code Online (Sandbox Code Playgroud)

(SSL.GetClientCertificate只是一个帮助方法,它打开My本地计算机上的存储并检索相应的证书(作为X509Certificate2).正在返回正确的证书.我也尝试从具有相同结果的文件中加载证书.)

事实上,当我到达Dim Response As...并且它实际上尝试打开连接时,我得到一个400 Bad Request返回以下正文:

400 Bad Request
No required SSL certificate was sent
-----------------------------------
nginx/1.0.10
Run Code Online (Sandbox Code Playgroud)

我们正在使用我们自己的CA,它LocalMachine\TrustedRootCertificationAuthorities在我的机器上有证书.客户端证书有效但验证失败,因为我们的CA未公开OCSP端点.如果我创建一个X509Chain并要求它验证链而不检查撤销,那么一切都会通过.

所以我的问题是......为什么证书不随请求一起发送?我不相信它应该在发送之前尝试验证客户端证书(这是服务器工作).

我不会在Wireshark日志中淹没你,但客户端没有发送证书.总之,我得到......

  • [出]客户你好
  • [In]服务器你好
  • [In]证书
  • [In]服务器Hello完成
  • [Out]证书,客户密钥交换,更改密码规范,加密握手消息
  • [In]更改密码规范,加密握手消息
  • [Out]应用程序数据(大概是GET请求)
  • [In]应用数据(推测为400)
  • [In]加密警报(终止频道)

认为 nginx正在做一些聪明的事情,而不是在我发送证书时没有死亡,它重新协商允许它发送一个400响应体(而不是首先创建一个通道)

在任何情况下,我都不会发送真正的问题证书.有谁知道为什么?

如果它有帮助,nginx的日志坚持没有发送证书(而不是证书无效):

2012/11/22 14:16:26 [info] 27755#0:*799客户端在读取客户端请求头时没有发送所需的SSL证书,客户端:10.0.0.200,服务器:10.0.0.100,请求:"GET/state HTTP /1.1",主持人:"10.0.0.100"

请不要使用下面的代码 - 它效率低,不可靠,仅用于测试

回复:获得证书:

Public Shared Function GetClientCertificate() As X509Certificate2
    Dim Store As New X509Store(StoreName.My, StoreLocation.LocalMachine)
    Dim Ret As X509Certificate2 = Nothing

    Try
        Store.Open(OpenFlags.ReadOnly Or OpenFlags.OpenExistingOnly)
        For Each Certificate In Store.Certificates
            If Certificate.SubjectName.Name = "The subjectname of our certificate" Then
                Ret = Certificate
                Exit For
            End If
        Next
    Finally
        Store.Close()
    End Try
    Return Ret
End Function
Run Code Online (Sandbox Code Playgroud)

Cod*_*ter 4

您需要一个具有可访问私钥的证书,以便能够将其用作客户端(或服务器)证书。

只要您授予需要使用证书的任何用户对其私钥的访问权限,就可以将证书存储在计算机证书存储中。您无法使用 .cer 对客户端进行身份验证,因为它仅包含公钥。您可以通过为用户安装客户端证书并使用浏览器访问 URL 来测试所有内容。如果您收到一个弹出窗口来选择证书,则表明它已正确安装(对于该用户)。