首页 > 解决方案 > 为什么服务器可能不会收到附加到使用 HttpClient 的请求的证书?

问题描述

我们正在尝试连接到一个端点,该端点只是验证证书是否已正确附加。

我们的代码很简单:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

using (var handler = new HttpClientHandler())
{
    var rawcert = File.ReadAllText(@"C:\OpenSSL\bin\cert.pem");
    var rawkey = File.ReadAllText(@"C:\OpenSSL\bin\private.key");

    var provider = new CertificateFromFileProvider(rawcert, rawkey);
    var certificate = provider.Certificate;

    handler.ClientCertificateOptions = ClientCertificateOption.Manual;
    handler.ClientCertificates.Add(certificate);
    handler.ServerCertificateCustomValidationCallback +=
    (HttpRequestMessage req, X509Certificate2 cert2, X509Chain chain, SslPolicyErrors err) =>
    {
        Trace.WriteLine($"Sender: {req}");
        Trace.WriteLine($"cert: {cert2}");
        Trace.WriteLine($"chain: {chain}");
        Trace.WriteLine($"sslPolicyErrors: {err}");
        return true;
    };

    using (var client = new HttpClient(handler))
    {
        var response = await client.GetStringAsync("https://{uri}/mtlsTest");
        return response;
    }
}

(这是一个用于概念验证的沙盒环境,因此我们现在可以轻松地缩短 ValidationCallback。)

我们可以看到附加的证书在回调中看起来格式正确(来源和主题是预期的),但是我们从服务器收到一个响应,表明没有附加证书。为什么会这样?

我们还尝试将证书导出为 apfx并附加该证书而不是原始pem文件,结果相同。

更新

感谢下面来自@bartonjs 和@Crypt32 的有用评论,我们尝试添加私钥(使用来自@stef-heyenrath 的方便的Nuget 包),但是尽管这导致我们添加到处理程序的证书显示HasPrivateKey=true

在此处输入图像描述

...当 ValidationCallback 触发时,X509Certificate2跟踪HasPrivateKey=false

在此处输入图像描述

...我们得到与以前相同的错误 - 服务器从不承认收到证书。

如果我们将.pem和私钥打包成.pfxusing open ssl: pkcs12 -inkey private.key -in cert.pem -export -out cert.pfx ... 那么我们再次得到相同的结果,并且服务器找不到证书。同样,如果我们在个人存储中安装证书并从那里加载它(结果相同)。使用 Wireshark 进行的检查表明该证书从未被附加。

为什么会这样?上面的完整修改代码。

标签: c#.netx509certificatedotnet-httpclientx509certificate2

解决方案


这里最初的问题是我们的测试主机提供的格式错误的证书。

另一个问题(一旦我们有一个好的证书可以使用)是NuGet 包的CertificateFromFileProvider方法的输出。OpenSSL.X509Certificate2Provider

无论出于何种原因,创建的证书都无法正常工作。采用相同的输入文件并.pfx使用OpenSSL生成一个可以正常工作的结果X509Certificate2


推荐阅读