使用证书访问 .NET Framework 中的 Web 服务时无法建立信任连接

Could not establish trust connection when accessing webservices within .NET Framework with certificate

我正在尝试调用 Web 服务(不是我的),在 Visual Studio 2008 年内对其进行服务引用。根据它的所有者的说法,它需要一个证书,他们出于测试目的提供了证书。

我在证书、SSL 和其他方面绝对是新手,所以我可能会在这里做一些非常错误的事情。不管怎样,这就是我所做的。

首先,我在我的客户端机器上注册了 P12 文件及其密码(也提供)。 然后,我使用 VS2008 中的服务引用选项引用该服务,并指向他们的 URL(顺便说一下,它使用 VPN 隧道)以便在 windows 表单应用程序中调用它。它们的所有底层方法都被生成的程序集识别。

这是我使用的代码:

WebServiceClient client = new WebServiceClient();
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);

store.Open(OpenFlags.ReadOnly);
X509Certificate2 certificate = store.Certificates[0]; 
client.ClientCredentials.ClientCertificate.Certificate = certificate;

client.ReturnSomeData(); //Error here

在最后一行,抛出以下异常:

Could not establish trust relationship for the SSL/TLS secure channel with authority '<webservice URI here>'

内部异常都是同样的2层深,第三层是

The remote certificate is invalid according to the validation procedure

问题是,我可以在 SoapUI 上使用那个证书调用那个方法,然后返回数据

另外,我看过 Marc Gravel 发布的疑难解答 here,所以...

  1. 你有服务器的 DNS 和视线吗?
  2. 您使用的证书名称是否正确? 是的,我用Immediate检查过。
  3. 证书还有效吗? 希望。如果 SoapUI 接受了它,我想是吗? (这里真的有我的疑惑)
  4. 配置不当的负载均衡器是否把事情搞砸了? 也没有解释 SoapUI 的行为。
  5. 新服务器机器的时钟设置是否正确(即 UTC 时间是否正确[忽略本地时间,这在很大程度上是无关紧要的])- 这对 WCF 来说当然很重要,所以可能会影响常规 SOAP? 不知道是否适用。
  6. 是否存在证书信任链问题?如果你从服务器浏览到soap服务,你能得到SSL吗? 其实,有。 Chrome 报告 The website's identity could not be confirmed。我认为这是因为我们在这里使用 VPN 连接。有问题吗?
  7. 服务器的机器级代理设置是否正确? (与用户的代理不同);请参阅 XP / 2003 的 proxycfg(不确定 Vista 等)再次,不会解释 SoapUI 的行为。

非常感谢任何帮助。

对我来说,这听起来像是存在信任问题。如果第三方服务给你他们的证书可能是 CA 证书而不是服务器证书本身。尝试在 windows 证书库中安装证书。有plenty of tutorials if you look for them.

如果他们给你的证书是 self-signed 那么你需要将他们的 CA 证书添加到 windows 证书存储区,这样系统才能信任颁发者,因此服务器证书被信任为嗯

更新: Here is another link 有导入根CA并信任的教程,记住导入证书是不够的,您必须明确信任它,请查看 link.

上的底部图片

我成功地收到了证书,直接从 .p12 文件导入它。 以下代码

X509Certificate2 certificate = new X509Certificate2();
certificate.Import(@"<FilePath>",password,X509KeyStorageFlags.DefaultKeySet);
client.ClientCredentials.ClientCertificate.Certificate = certificate;

client.ReturnSomeData();

是成功的,所以我现在坚持使用这个解决方案。不太理想,不过看这事急,待会再改。

仍然不是一个明确的答案,尽管这可能对遇到类似问题的人有所帮助。

更新

我想我明白了为什么这回答了这个问题。 因此,事实证明,我从商店检索证书的方式 仍然有问题。直接导入它可确保证书 存在 ,但客户端连接需要一些额外的步骤。

首先,在绑定中定义传输模式。

<binding name="<bindingName>">
        <security mode="Transport" >
            <transport clientCredentialType="Certificate" />
        </security>
</binding>

其次,确保 ServerCertificateValidationCallBack 回调进行正确的验证。看起来很糟糕,

ServicePointManager.ServerCertificateValidationCallback += 
    (sender, x509Certificate, chain, errors) => true;

可以用于非生产目的