收到的 WCF 服务器证书的部分链验证失败

Posted

技术标签:

【中文标题】收到的 WCF 服务器证书的部分链验证失败【英文标题】:Partial Chain validation failure of received WCF server certificate 【发布时间】:2020-02-24 15:57:43 【问题描述】:

我们正在集成一项服务,该服务使用客户端证书来验证我们与供应商服务器之间的 https 连接。我们生成了一个 CSR,供应商向我们提供了一个 p7b 文件,其中包含 2 个中间证书和一个受信任的根证书。然后,我们使用来自 CSR 的私钥创建了一个 pfx 二进制文件(我们可以匹配证书和密钥,因此我们知道从那个角度来看它们是正确的)。

我们使用 Vault 来存储我们的相互身份验证证书,因此 pfx 没有安装到 Windows Server 2012r2 上。

在我们的客户端代码中,我们执行以下操作:

var myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.Transport;
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;

var client = new ServiceClient(myBinding, new EndpointAddress("https://example.org"));
client.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2("cert.pfx", "****");
client.create(new model());

通过上述设置,我们会产生以下影响:

Windows 10 开发机器 - TLS 连接成功 Windows Server 2012r2 - TLS 连接失败

然后我们添加了一个验证回调:

ServicePointManager.ServerCertificateValidationCallback += ValidateServerCertificate;

private static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)

   // ...

此时sslPolicyErrorsSystem.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors

如果我们尝试构建自己的 SSL 链:

using (var chain = new X509Chain())

  var flag = X509VerificationFlags.NoFlag;
  chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
  chain.ChainPolicy.VerificationFlags = flag;

  var primaryCert = new X509Certificate2(certificate);

  var n = chain.Build(primaryCert);
  Console.WriteLine($"Flag: flag - string.Join(",", chain.ChainStatus.Select(x => $"x.StatusInformation.Trim() (x.Status)"))");

  return n;

我们得到了打印 - Flag: NoFlag - A certificate chain could not be built to a trusted root authority. (PartialChain)

所以我们将标志更改为X509VerificationFlags.AllowUnknownCertificateAuthority

这样做会导致证书链得到正确验证。

我们的问题是:

    我们在不同的机器上会产生不同的影响,因此我们的结论是 Win 10 对其检查没有那么严格。 Server 2012r2有什么理由拒绝这个链吗?

    如果我们使用验证标志X509VerificationFlags.AllowUnknownCertificateAuthority会不会有安全问题?

    我们可以在客户端的设置中设置这个标志,还是它必须是验证回调的一部分?

【问题讨论】:

【参考方案1】:

所以我们的结论是 Win 10 的检查没有那么严格

这是不正确的。 Windows 客户端和 Windows Server 操作系统共享相同的加密代码 (CAPI2) 和配置。

如果我们使用验证标志X509VerificationFlags.AllowUnknownCertificateAuthority?会不会有任何安全问题

是的,这个标志为MITM 攻击打开了大门。

我们可以在客户端的设置中设置这个标志,还是它必须是验证回调的一部分?

您真正需要的是解决问题。该错误表明服务器证书不是由受信任的 CA 颁发的。此 CA(服务器 TLS 证书的颁发者)被开发机器信任,因为开发者信任此 CA(管理员已在受信任的根存储中安装了开发 CA 证书)。

如果您从供应商处收到 CA 证书,则它们也必须安装在 Windows Server 2012 盒子上。这将自动解决问题。

【讨论】:

开发和服务器机器运行相同的组策略,因此它们都具有相同的根证书。我们找不到它们之间的任何区别。有没有办法找到可能导致问题的证书? 根证书(来自供应商)很可能是在 Windows 10 机器上手动安装的。在两台机器上运行 cermgr.msc 并比较受信任的根 CA 存储中的证书。 我们的服务器似乎没有该实用程序 - 我们使用 mmc 进行比较。颁发者来自 DigiCert - 服务器和开发者在受信任的根 CA 存储中拥有所有相同的 DigiCert 证书。 对不起,有一个错字。正确的是certmgr.msc。我会仔细检查从 TLS 握手收到的证书是否是预期的(来自 DigiCert)。我怀疑您端的配置错误或从服务器收到的证书错误。 然后 Windows Server 2012 框中缺少一个或多个 DigiCert 中间 CA 证书。根没问题。您可以在 Windows 10 盒子上的 Intermediate CAs 证书存储中找到它们。你一定会发现不一样的。

以上是关于收到的 WCF 服务器证书的部分链验证失败的主要内容,如果未能解决你的问题,请参考以下文章