调用ServerCertificateValidationCallback之前出现远程证书无效错误

本文关键字:证书 错误 无效 程证书 ServerCertificateValidationCallback 调用 | 更新日期: 2023-09-27 18:27:18

我在尝试连接到SOAP 1.1服务器时遇到异常。我从另一个组织收到了WSDL,并使用.net将其作为服务参考纳入我的项目中。

要求我们使用包含MTOM附件和HTTPgzip压缩。它还要求Web服务安全性(WS-Security)版本1.0(使用OASIS标准)使用X.509身份验证框架实现端到端安全。

我在c#中使用4.5.2.Net框架。

以下是我的app.config的相关部分,其中对潜在的敏感信息进行了编辑:

  <basicHttpBinding>
    <binding name="customHttpBinding" allowCookies="true" messageEncoding="Mtom">
      <security mode="TransportWithMessageCredential">
        <transport clientCredentialType="Certificate" />
        <message clientCredentialType="Certificate" />
      </security>
    </binding>
  </basicHttpBinding>
[snip]
<client>
  <endpoint address="YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
    binding="basicHttpBinding" bindingConfiguration="customHttpBinding"
    contract="SERVICENAME.BulkRequestTransmitterPortType"
    name="BulkRequestTransmitterPort">
    <identity>
      <certificateReference storeLocation="CurrentUser" x509FindType="FindBySerialNumber"
        findValue="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" />
    </identity>
  </endpoint>
</client>

X是我的密钥的序列号(确认在我的计算机存储中),Y是端点

以下是我创建和调用服务的部分(X是相同的证书):

  var transmitter = new BulkRequestTransmitterPortTypeClient();
  transmitter.ClientCredentials?.ClientCertificate.SetCertificate(
      StoreLocation.CurrentUser, 
      StoreName.My, 
      X509FindType.FindBySerialNumber, 
      "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
  var response = transmitter.BulkRequestTransmitter(
      securityHeader, 
      security, 
      ref businessHeader, 
      transmitterManifestReqDtl, 
      transmitterType);

它在最后一行爆炸,并出现以下错误:

ex  {"Could not establish trust relationship for the SSL/TLS secure channel with authority 'YYYYYYYYYYYY'."}    System.Exception {System.ServiceModel.Security.SecurityNegotiationException}
    +InnerException {"The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."}    System.Exception {System.Net.WebException}
        +InnerException {"The remote certificate is invalid according to the validation procedure."}    System.Exception {System.Security.Authentication.AuthenticationException}

每当我进行搜索时,我都会发现两个建议,第一个是确保服务器证书在我的可信存储中,并且第三方授权机构是可信的。我已经验证了这两个都在我本地计算机的存储中并且是可信的。第二个也是最常见的建议是重写ServicePointManager.ServerCertificateValidationCallback,返回true如下:

ServicePointManager.ServerCertificateValidationCallback = delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    return true;
};

尽管我很犹豫是否要尝试这个(即使在开发环境中我也不喜欢使用糟糕的做法),但我认为在调试中使用它是值得的。遗憾的是,断点从未命中。我在服务器CertificateValidationCallback关闭之前收到错误。

我现在不知所措。我不确定我做错了什么,因为我对配置所做的每一次更改都会在更早的时候产生错误,所以我认为我走在了正确的道路上,但不确定验证过程失败的原因以及如何解决。我很感激能提供的任何帮助。

调用ServerCertificateValidationCallback之前出现远程证书无效错误

这是因为有问题的服务器没有使用证书。如果您通知.net希望从服务器获得一个证书,那么它将在到达ServerCertificateValidationCallback之前失败,并显示此错误消息。

不幸的是,我不是心灵感应者,可以判断出是什么导致了你的问题。不过,我可以提供一些见解。

仅出于调试目的,您可以获得连接失败的确切原因。使用此回调委托:

ServicePointManager.ServerCertificateValidationCallback = delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    return true;
};

并在委托调用上设置断点。激发时,请使用调试器检查chain参数。ChainElements属性包含X509ChainElement对象的集合。每个对象都与链中的特定证书、链中每个证书的状态和证书状态(通过ChainElementStatus)相关联。请注意,链元素的状态是累积的,这意味着错误从最顶层的证书向下传播。换句话说,ChainElementStatus成员将包含与特定ChainElement相关联的错误加上来自上层的组合错误。

一旦发现并解决了问题,请将该代表除名。

另一个选项是将远程服务器的证书文件(只有公共证书)传递给certutil:

certutil -verify -urlfetch path'remoteserver.cer

输出可能有点复杂,但它将提供额外的信息,而X509Chain调试无法获得这些信息。最常见的问题(在不受信任的根之后)是RevocationOffline,certutil将显示吊销检查的详细信息,包括每个URL的可用性和有效性。