尽管设置了ServerCertificateValidationCallback,但仍无法创建SSL / TLS安全通道


83

我正在尝试建立SSL / TLS连接以使用自签名证书测试服务器。通过不安全的渠道进行的通信没有问题。

这是我基于此解决方案编写的示例代码: 允许带有HttpClient C#的 不受信任的SSL证书忽略证书错误?.NET客户端连接到ssl Web API

ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

var c = new HttpClient();
var r = c.GetAsync("https://10.3.0.1:8443/rest/v1").Result;
if (r.IsSuccessStatusCode)
{
    Log.AddMessage(r.Content.Get<string>());
}
else
{
    Log.AddMessage(string.Format("{0} ({1})", (int)r.StatusCode, r.ReasonPhrase));
}

还尝试了这个:

var handler = new WebRequestHandler();
handler.ServerCertificateValidationCallback = delegate { return true; };
var c = new HttpClient(handler);
...

还有这个

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

但是每次我有一个例外:

InnerException: System.Net.Http.HttpRequestException
   _HResult=-2146233088
   _message=An error occurred while sending the request.
   HResult=-2146233088
   IsTransient=false
   Message=An error occurred while sending the request.
   InnerException: System.Net.WebException
        _HResult=-2146233079
        _message=The request was aborted: Could not create SSL/TLS secure channel.
        HResult=-2146233079
        IsTransient=false
        Message=The request was aborted: Could not create SSL/TLS secure channel.
        Source=System
        StackTrace:
             at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
             at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
        InnerException: 

我做错了什么?为什么我无法连接到该服务器(该服务器具有无效的自签名证书)

Answers:


161

您可以使用ServerCertificateValidationCallback正确地执行此操作。这不是您面临的问题。您面临的问题很可能是SSL / TLS协议的版本。

例如,如果您的服务器仅提供SSLv3和TLSv10,而客户端需要TLSv12,则您将收到此错误消息。您需要做的是确保客户端和服务器都支持一个通用的协议版本。

当我需要一个能够连接到尽可能多的服务器(而不是尽可能地安全)的客户端时,可以使用此方法(与设置验证回调一起使用):

  ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

1
我有一个类似的问题。由于POODLE攻击,我们被迫关闭服务器上的TLS 1.0。当我这样做时,第三方应用程序停止工作。反汇编显示的代码与您的代码相似。它使用webclientc.SendAsync而不是GetAsync。如果将代码复制到consoleapp进行测试,则可以重现该错误,并通过添加ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11可以正常工作。我坚信服务器和客户端之间将进行某种形式的握手,以发现要使用的TLS版本?为什么禁用1.0时它不会自动选择1.1?
Engern '16

3
谢谢!为此苦苦挣扎了3个小时。添加此行对我ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Thomas T

1
请注意,.NET的较新版本默认情况下已启用此功能,我们要做的就是将.NET版本设置为4.6.1
martinh_kentico

1
确切地说,无论您是否在乎,无论是否有效。该回调使您可以简单地避免对该证书进行任何安全检查。
Wapac

1
很好的答案,我觉得这个ServicePointManager.SecurityProtocol值应该是默认值。或者至少应该在抛出的Exception内部直接有更多的见解。
乍得

28

就在今天,我们一直在解决相同的问题,您要做的就是增加.NET的运行时版本

4.5.2不适用于我们上述问题,而4.6.1可以

如果需要保留.NET版本,请设置

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

1
您使用了哪种变体以及精确度如何?
martinh_kentico

1
我有一个.NET 4.5应用程序,从今天开始,将无法在特定的SSL站点上使用。如果我将其更改为4.6.1,则可以正常工作,但我无法真正更改。我不确定该怎么做:|
Tsury

16

就像对仍然遇到此问题的任何人的跟进一样,我已经添加了ServicePointManager.SecurityProfile选项,如解决方案中所述:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

但是,我仍然收到相同的“请求已中止:无法创建SSL / TLS安全通道”错误。我试图使用HTTPS SOAP API接口(例如,几年前安装的语音邮件,IP电话系统等)连接到一些较旧的语音服务器。这些仅支持SSL3连接,因为它们最近几年才更新。

有人会认为将SSl3包含在SecurityProtocols列表中可以解决此问题,但事实并非如此。我可以强制连接的唯一方法是仅包含Ssl3协议,而不包含其他协议:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

然后,连接通过了-对我来说似乎是个错误,但是直到最近我为这些已经存在了多年的服务器提供的工具上才开始引发错误-我相信Microsoft已经开始推出更新了此功能的系统更改除非没有其他选择,否则强制TLS连接的行为。

无论如何,如果您仍然遇到一些旧站点/服务器,则值得尝试一下。


1
我们有一个CUCMPowerShell模块,用于通过PowerShell使用Cisco Unified Communications AXL api,您的答案通过添加来帮助我们解决此问题[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Ssl3。谢谢!完整代码可以在Invoke-CUCMSOAPAPIFunction中
Chris Magnuson,

2
@Jeff-查看链接的文章。我认为这可以解释为什么Ssl3无法正常工作,并提出了两种重新启用Ssl3的方法。docs.microsoft.com/en-us/dotnet/framework/migration-guide/…–
斯科特(Scott)

4

移动此行:ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

在此行之前:HttpWebRequest request =(HttpWebRequest)WebRequest.Create(uri);

原始文章:KB4344167安全更新破坏了TLS代码


1
尝试以上所有方法均无济于事后,这就是答案:在创建HttpWebRequest之前,必须先设置ServicePointManager。
亨利·鲁斯

1

在我的情况下,客户端和服务器上都启用了TLS1_2,但是服务器使用的是MD5,而客户端禁用了它。因此,请在http://ssllabs.com上同时测试客户端和服务器,或者使用openssl / s_client测试以查看发生了什么。另外,使用Wireshark检查选定的密码。


1

TLS 1.0和1.1现已终止。我们的Amazon Web服务器上的软件包已更新,我们开始收到此错误。

答案在上面,但您不应再使用tlstls11再使用。

专门针对ASP.Net,将其添加到您的一种启动方法中。

        public Startup()
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12;

但我敢肯定,类似的事情在其他情况下也会起作用。


0

如果您使用的是新域名,并且已完成上述所有操作,但仍收到相同的错误,请检查是否清除了PC上的DNS缓存。 清除DNS以获取更多详细信息。

Windows®8

如果使用Windows 8,要清除DNS缓存,请执行以下步骤:

在键盘上,按Win + X打开WinX菜单。

右键单击“命令提示符”,然后选择“以管理员身份运行”。

运行以下命令:

ipconfig / flushdns

如果命令成功,系统将返回以下消息:

Windows IP配置成功刷新了DNS解析器缓存。

Windows®7

如果使用Windows 7,要清除DNS缓存,请执行以下步骤:

单击开始。

在“开始”菜单搜索文本框中输入cmd。

右键单击“命令提示符”,然后选择“以管理员身份运行”。

运行以下命令:

ipconfig / flushdns

如果命令成功,系统将返回以下消息:Windows IP配置成功刷新了DNS解析器缓存。


ipconfig /flushdns在C#中?
Kiquenet

0

我遇到了这个线程,因为我也遇到了“无法创建SSL / TLS安全通道”错误 就我而言,我试图使用PowerShell从PowerShell访问Siebel配置REST API Invoke-RestMethod,但上述建议均无济于事。

最终,我偶然发现了问题的原因:我正在联系的服务器需要客户端证书认证。

为了使呼叫正常工作,我必须向客户端证书(包括私钥)提供-Certificate参数:

$Pwd = 'certificatepassword'
$Pfx = New-Object -TypeName 'System.Security.Cryptography.X509Certificates.X509Certificate2'
$Pfx.Import('clientcert.p12', $Pwd, 'Exportable,PersistKeySet')
Invoke-RestMethod -Uri 'https://your.rest.host/api/' -Certificate $Pfx -OtherParam ...

希望我的经验可以对其他有我这个问题风味的人有所帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.