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

标签 .net security ssl nginx httpwebrequest

我正在尝试使用 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()

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

就目前情况而言,当我到达 Dim Response As... 并且它实际上尝试打开连接时,我收到一个返回 400 Bad Request 的正文:

400 Bad Request
No required SSL certificate was sent
-----------------------------------
nginx/1.0.10

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

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

我不会让您在 Wireshark 日志中泛滥,但客户端不会发送证书。简而言之,我得到...

  • [Out] 客户您好
  • [In] 服务器问候
  • [在]证书
  • [In] 服务器问候完成
  • [Out] 证书、客户端 key 交换、更改密码规范、加密握手消息
  • [In] 更改密码规范,加密握手消息
  • [Out] 应用程序数据(大概是 GET 请求)
  • [In] 申请数据(大概是 400)
  • [In] 加密警报(终止 channel )

认为 nginx 正在做一些聪明的事情,而不是在我未能发送证书时死掉,它重新协商以允许它发送一个 400 响应主体(而不是在第一名)

无论如何,我不会发送真正问题的证书。有谁知道为什么吗?

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

2012/11/22 14:16:26 [info] 27755#0: *799 client sent no required SSL certificate while reading client request headers, client: 10.0.0.200, server: 10.0.0.100, request: "GET /state HTTP/1.1", host: "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

最佳答案

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

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

关于.net - HttpWebRequest 似乎没有发送客户端 SSL 证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13514628/

相关文章:

node.js - 是否可以在一个安全端口上运行网络服务器和 socket.io?

mysql - sequel pro 只在 mycli 中检查 "connect using ssl"相当于什么?

c# - Bloomberglp.Blpapi.Session 上的 EventDispatcher 有什么用?

security - Delphi和Microsoft ATL安全问题

c# - 精神上试图理清密码<->数据库方案 - 这通常是如何完成的?

security - 以某个用户的代理身份登录

java - TlsPremasterSecret SecretKeyFactory 不可用

c# - 如何以管理员权限运行任何exe?

.net 抽象类的多重继承

.net - 正则表达式在双花括号之间得到任何东西