无法与'*'建立安全的SSL/TLS通道

24
我必须调用一个有SSL证书的PHP Web服务。我的.NET 3.5类库在Visual Studio 2010中使用“添加服务引用”来引用该Web服务(是WCF吧?)。

当调用Web服务的主要方法时,我收到以下错误信息:

无法与'{base_url_of_WS}'建立安全通道的SSL/TLS。

我尝试了很多方法,比如

System.Net.ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); 
 public bool CheckValidationResult(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        return true;
    }

但是它不起作用。同时,我已经在自己的计算机上安装了证书。

*额外信息:当我在“添加服务引用”中使用wsdl位置时,同样的错误会发生。之前我尝试过使用静态wsdl。

alt text


不,完全没有,它只是被发出并签署了。 - Casper Broeren
1
你有没有办法尝试通过浏览器连接到 Web 服务(比如查看服务元数据)?这将有助于确定问题是证书问题还是 WCF 内部问题。 - Paul Turner
我遇到了类似的异常 - 请参见:http://stackoverflow.com/questions/8594684/differences-between-webservice-clients-written-in-net2-0-and-net4-0 - Mateusz
@PaulTurner 如果 Web 服务可以通过浏览器正常工作,那么这意味着什么?WCF 中存在问题吗? - Jimenemex
10个回答

34

这正是我所遇到的问题。在另一篇文章中,我得到了一个提示来更改配置。对我而言,以下方法有效:

<bindings>
  <basicHttpBinding>
    <binding name="xxxBinding">
      <security mode="Transport">
        <transport clientCredentialType="Certificate"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

1
谢谢。传输部分正是我所需要的!经过数小时的测试,终于解决了它。 :) - KoalaBear
传输线路也为我解决了这个问题。尽管我在代码中手动添加了正确的受信任证书,但在我的.config文件中添加了那行代码之前,它无法正确识别它。谢谢! - jozolo
同样的问题,通过这个配置设置解决了。谢谢,我花了3个小时在那上面。 - Nicolas R
谢谢!解决了我的问题,但在<customBinding>标记内。 - mlaribi

30

问题

当我从ASP.NET Core MVC项目调用第三方API时,遇到了相同的错误信息。

无法为SSL/TLS与权限'{base_url_of_WS}'建立安全通道。

解决方法

原来第三方API的服务器需要TLS 1.2。为了解决这个问题,我在控制器的构造函数中添加了以下代码:

System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;

4
除非您明确不想要 SSL 连接,否则应该使用“或”运算符来添加 TLS 值,而不是直接赋值:System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12; - mrfelis

12

是的,不受信任的证书可能会导致此问题。打开 Web 服务并使用浏览器工具查看证书路径,查看 Web 服务的证书路径。您可能需要将一个或多个中间证书安装到调用 Web 服务的计算机上。在浏览器中,您可能会看到“证书错误”的选项,并在进一步调查时看到“安装证书”选项 - 这可能是你缺失的证书。

我的特定问题是缺少Geotrust Geotrust DV SSL CA 中间证书,该证书在2010年7月升级其根服务器后丢失了。 https://knowledge.geotrust.com/support/knowledge-base/index?page=content&id=AR1422

(2020更新 此处保留了无效链接: https://web.archive.org/web/20140724085537/https://knowledge.geotrust.com/support/knowledge-base/index?page=content&id=AR1422)


5
我们在新的Web服务器上遇到了一个问题,即.aspx页面调用web服务时出现问题。我们没有向应用程序池用户授予机器证书的权限。在我们授予权限给应用程序池用户之后,该问题得到解决。

你能详细说明一下吗?你是如何授予这个访问权限的? - fahadash

2
如果有帮助的话,使用新的Microsoft Web Service Reference Provider工具(适用于.NET Standard和.NET Core),我需要按照以下方式将以下行添加到绑定定义中:
binding.Security.Mode = BasicHttpSecurityMode.Transport;
binding.Security.Transport = new HttpTransportSecurity{ClientCredentialType = HttpClientCredentialType.Certificate};

这实际上与Micha的答案相同,但是以代码形式呈现,因为没有配置文件。

因此,为了将绑定与Web服务的实例化合并,我做了以下操作:

 System.ServiceModel.BasicHttpBinding binding = new System.ServiceModel.BasicHttpBinding();
 binding.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.Transport;
 binding.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Certificate;
 var client = new WebServiceClient(binding, GetWebServiceEndpointAddress());

当你定义Web服务时,WebServiceClient是其正确的名称。


2

确保您以管理员身份运行Visual Studio。


1
这个错误可能有很多原因,上次我通过修改Reference.svcmap文件并更改WSDL文件的引用方式来解决它。
抛出异常:
<MetadataSource Address="C:\Users\Me\Repo\Service.wsdl" Protocol="file" SourceId="1" />
<MetadataFile FileName="Service.wsdl" ... SourceUrl="file:///C:/Users/Me/Repo/Service.wsdl" />

工作正常:
<MetadataSource Address="https://server.domain/path/Service.wsdl" Protocol="http" SourceId="1" />
<MetadataFile FileName="Service.wsdl" ... SourceUrl="https://server.domain/path/Service.wsdl" />

这似乎很奇怪,但我已经复制了它。这是在.NET 4.5和4.7控制台应用程序以及.NET WebAPI网站上的4.7中发生的。


1

有关代码出现了相同的错误:

X509Certificate2 mycert = new X509Certificate2(@"C:\certificate.crt");

通过添加密码解决:

X509Certificate2 mycert = new X509Certificate2(@"C:\certificate.crt", "password");

你正在推送这个中间证书吗? - amindomeniko

0
这是我解决问题的方法:
1)确保您以管理员身份运行Visual Studio
2)安装并运行winhttpcertcfg.exe以授予权限

https://msdn.microsoft.com/en-us/library/windows/desktop/aa384088(v=vs.85).aspx

命令类似于以下内容:(输入您的证书主题和服务名称)

winhttpcertcfg -g -c LOCAL_MACHINE\MY -s "certificate subject" -a "NetworkService"
winhttpcertcfg -g -c LOCAL_MACHINE\MY -s "certificate subject" -a "LOCAL SERVICE"
winhttpcertcfg -g -c LOCAL_MACHINE\MY -s "certificate subject" -a "My Apps Service Account"

1
应该提到的是,winhttpcertcfg在Win 2008 R2及更高版本中缺乏官方支持。有关导入证书并在Windows Server 2012 R2上授予权限的问题,请参考http://serverfault.com/questions/620013/importing-a-certificate-and-granting-permissions-on-windows-server-2012-r2 - Eric Herlitz

0
对于我而言,解决方案是更改SecurityProtocolType

我在创建BasicHttpsBinding之前插入了此代码。

顺便说一句,我是从代码端创建绑定的,而不是从配置文件中创建的。

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接