无法build立SSL / TLS安全通道 – SOAP的信任关系

我有一个简单的Web服务调用,由.NET(C#)2.0 Windows应用程序生成,通过由Visual Studio生成的Web服务代理,也用C#(2.0)编写的Web服务。 这已经工作了好几年了,而且还在十几个地方继续这样做。

新网站的新安装会遇到问题。 尝试调用Web服务时,失败并显示消息:

无法build立SSL / TLS安全通道的信任关系

Web服务的URL使用SSL(https://) – 但是这已经在许多其他位置上工作了很长时间(并继续这样做)。

我在哪里看? 这可能是Windows和.NET之间的安全问题吗? 如果是这样,我在哪里build立信任关系? 我迷路了!

思考(基于过去的痛苦):

  • 你有DNS和视线到服务器?
  • 你是否使用证书中的正确名称?
  • 证书是否仍然有效?
  • 是一个糟糕的configuration负载平衡器搞砸了?
  • 新的服务器机器是否有正确的时钟设置(即使UTC时间是正确的[忽略当地时间,这在很大程度上是无关紧要的)) – 这对WCF肯定很重要,所以可能会影响常规的SOAP?
  • 有证书信任链问题吗? 如果您从服务器浏览到soap服务,您能获得SSL吗?
  • 服务器的机器级代理设置是否正确? (这与用户的代理不同); 看到XP / 2003的proxycfg(不知道Vista等)

以下代码片段将修复您所调用的服务器上的SSL证书有问题的情况。 例如,它可能是自签名的,或者证书和服务器之间的主机名可能不匹配。

如果您在直接控制之外调用服务器, 这是非常危险的 ,因为您不能确定您正在与您认为已连接的服务器通信。 但是,如果您正在处理内部服务器并且获得“正确”证书不切实际,请使用以下方式告诉Web服务忽略证书问题和勇敢的士兵。

前两个使用lambdaexpression式,第三个使用正则代码。 第一个接受任何证书。 最后两个至less检查证书中的主机名是否是您期望的。
希望你觉得有帮助

//Trust all certificates System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true); // trust sender System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, cert, chain, errors) => cert.Subject.Contains("YourServerName")); // validate cert by calling a function ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate); // callback used to validate the certificate in an SSL conversation private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors) { bool result = false; if (cert.Subject.ToUpper().Contains("YourServerName")) { result = true; } return result; } 

非常简单的“全部捕捉”解决scheme是这样的:

 System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

sebastian-castaldi的解决scheme更为详细。

我个人最喜欢下面的解决scheme:

 using System.Security.Cryptography.X509Certificates; using System.Net.Security; 

…然后在请求获取错误之前,请执行以下操作

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

在咨询Luke的解决scheme后find了这个

如果你使用Windows 2003,你可以试试这个:

打开Microsoftpipe理控制台(开始 – >运行 – > mmc.exe);

select文件 – >添加/删除pipe理单元;

在“独立”选项卡中,select“添加”;

select证书pipe理单元,然后单击添加;

在向导中,select“计算机帐户”,然后select“本地计算机”。 按“完成”结束向导;

closures“添加/删除pipe理单元”对话框;

导航到证书(本地计算机)并select要导入的商店:

如果您拥有颁发证书的公司的根CA证书,请select受信任的根证书颁发机构;

如果您拥有服务器本身的证书,请select“其他人员”

右键单击商店并select“所有任务” – >“导入”

按照向导提供您拥有的证书文件;

之后,只需重新启动IIS,然后再次尝试调用Web服务。

参考: http : //www.outsystems.com/NetworkForums/ViewTopic.aspx ?Topic= Web- Services: -Could-not-establish-trust-relationship-for- the-SSL/ TLS- …

如果你不想盲目信任每个人,只为某些主机制定一个信任例外,那么下面的解决scheme是更合适的。

 public static class Ssl { private static readonly string[] TrustedHosts = new[] { "host1.domain.com", "host2.domain.com" }; public static void EnableTrustedHosts() { ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => { if (errors == SslPolicyErrors.None) { return true; } var request = sender as HttpWebRequest; if (request != null) { return TrustedHosts.Contains(request.RequestUri.Host); } return false; }; } } 

然后只需在您的应用程序启动时调用Ssl.EnableTrustedHosts。

微软的SSL诊断工具可以帮助识别问题。

更新链接现在已经修复。

卢克写了一篇关于这个很好的文章..非常直截了当的..给这个试试看

卢克的解决scheme

原因(引自他的文章(不要诅咒))“..上面的代码的问题是,如果你的证书是无效的,它不起作用。为什么我会张贴到一个网页与无效的SSL证书?我很便宜,而且我不想付Verisign或者其他的一个** – *作为我的testing盒的证书,所以我自己签了名。当我发送请求时,我得到了一个可爱的例外:

System.Net.WebException 底层连接已closures。 无法与远程服务器build立信任关系。

我不知道你,但对我来说,exception看起来像是由于我的代码中的一个愚蠢的错误导致POST失败的东西。 所以我一直在寻找,调整和做各种奇怪的事情。 只有在我search到这个事情之后,我发现在遇到一个无效的SSL证书之后的默认行为是抛出这个exception。 ..”

我刚刚遇到这个问题。 我的解决scheme是通过手动同步到时间服务器来更新系统时间。 要做到这一点,你可以:

  • 用鼠标右键单击任务栏中的时钟
  • selectAdjust Date/Time
  • selectInternet Time选项卡
  • 点击Change Settings
  • selectUpdate Now

在我的情况下,这是同步不正确的,所以我不得不点击几次,才能正确更新。 如果继续更新不正确,您甚至可以尝试从服务器下拉菜单中使用不同的时间服务器。

我在Internet Explorer中的.NET应用程序中遇到了类似的问题。

我解决了在我的案例中添加证书(VeriSign Class 3证书)到可信编辑证书的问题。

转到“Internet选项” – >“内容” – >“发布者”并将其导入

如果从以下位置导出证书,您可以获得证书:

Internet选项 – >内容 – >证书 – >中级证书颁发机构 – > VeriSign 3级公共主authentication机构 – G5

我有这样的错误运行在一个web服务器与URL像:

 abdomain.com 

但没有证书,所以我得到了一个DNS调用

 a_b.domain.com 

只是提示这个解决scheme在这里,因为这在谷歌上来了。

就我而言,我试图在使用IIS 7的Visual Studio环境中testingSSL

这就是我最终做的工作:

  • 在我的网站IIS右边的“绑定…”部分,我必须添加“https”绑定到端口443,并select“IIS Express开发证书”。

  • 在我的网站下的“高级设置…”部分中,我必须将“启用的协议”从“http”更改为“https”。

  • 在“SSL设置”图标下,我为客户端证书select了“接受”。

  • 然后,我不得不回收应用程序池。

  • 我还必须使用mmc.exe将本地主机证书导入我的个人存储。

我的web.config文件已经configuration正确,所以当我把上述所有内容整理出来后,我就可以继续我的testing了。

对于通过VS客户端遇到此问题的用户,一旦成功添加服务引用,并尝试执行第一个调用,就会得到以下exception:“底层连接已closures:无法build立SSL / TLS安全通道的信任关系”你正在使用(像我的情况)一个端点URL与IP地址,并得到这个exception,那么你应该需要重新添加服务引用执行此步骤:

  • 在Internet Explorer上打开端点URL。
  • 点击证书错误(地址栏中的红色图标)
  • 点击查看证书。
  • 抓住颁发给:“名称”,并更换IP地址或任何我们正在使用的名称,并得到这个“名称”的错误。

再试一次 :)。 谢谢

如果没有工作不好的证书,当ServerCertificateValidationCallback返回true; 我的ServerCertificateValidationCallback代码:

 ServicePointManager.ServerCertificateValidationCallback += delegate { LogWriter.LogInfo("Проверка сертификата отключена, на уровне ServerCertificateValidationCallback"); return true; }; 

我的代码防止执行ServerCertificateValidationCallback:

  if (!(ServicePointManager.CertificatePolicy is CertificateValidation)) { CertificateValidation certValidate = new CertificateValidation(); certValidate.ValidatingError += new CertificateValidation.ValidateCertificateEventHandler(this.OnValidateCertificateError); ServicePointManager.CertificatePolicy = certValidate; } 

OnValidateCertificateError函数:

 private void OnValidateCertificateError(object sender, CertificateValidationEventArgs e) { string msg = string.Format(Strings.OnValidateCertificateError, e.Request.RequestUri, e.Certificate.GetName(), e.Problem, new Win32Exception(e.Problem).Message); LogWriter.LogError(msg); //Message.ShowError(msg); } 

我禁用了CertificateValidation代码和ServerCertificateValidationCallback运行得非常好