将自定义根 CA 与 HttpClient 结合使用

Yev*_*y P 5 c# ssl ca dotnet-httpclient .net-core

在 C# 中,使用 HttpClient 时,如何连接到使用自签名证书(用于测试)或不属于计算机信任存储的自定义 CA 的 https 服务器?请注意,我不需要客户端证书,只需要 HttpClient 来验证未由计算机上受信任的根 CA 之一签名的服务器证书。我知道我可以将自签名证书或 CA 添加到计算机上的本地信任存储中,但假设我想避免这样做。我需要的基本上是为正在运行的应用程序提供额外的根 CA。

据我所知,在其他语言中有很简单的方法可以做到这一点:

  1. 在java中,使用“javax.net.ssl.trustStore”系统属性。

  2. 在 Node.js 中,使用 NODE_EXTRA_CA_CERT 环境变量。

但到目前为止,我在 .Net 上找不到类似的东西。有没有像上面这样简单的方法呢?

Wil*_*der 2

我为此奋斗了一段时间,除了用户 evk 在https://learn.microsoft.com/en-us/的链接中提到的“编写自己的回调处理程序”之外,似乎没有什么好的答案上面注释中的dotnet/api/system.net.http.httpclienthandler.servercertificatecustomvalidationcallback?view=net-5.0,但这并没有真正解释该回调中应该包含什么内容。然后我偶然发现了这个评论https://github.com/dotnet/runtime/issues/39835#issuecomment-663020581

事实证明,使用自定义根证书非常简单。基本上,更改链策略以使用自定义根,添加自定义根,然后在链上调用构建。

private static bool ServerCertificateCustomValidation(
    HttpRequestMessage requestMessage,
    X509Certificate2? certificate,
    X509Chain? chain,
    SslPolicyErrors sslErrors)
{
    if (certificate == null) return false;
    if (chain == null) return false;
    chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
    chain.ChainPolicy.CustomTrustStore.Add(GetTrustedRootCert());
    return chain.Build(certificate);
}
Run Code Online (Sandbox Code Playgroud)

请记住,您可能仍想检查其他一些事情,例如是否存在其他策略错误。该答案仅涵盖使用自定义受信任根。