提问人:Simon Dugré 提问时间:5/19/2010 最后编辑:InteXXSimon Dugré 更新时间:8/26/2023 访问量:1486263
请求已中止:无法创建 SSL/TLS 安全通道
The request was aborted: Could not create SSL/TLS secure channel
问:
由于以下错误消息,我们无法连接到HTTPS服务器:WebRequest
The request was aborted: Could not create SSL/TLS secure channel.
我们知道服务器没有有效的 HTTPS 证书和使用的路径,但为了绕过这个问题,我们使用从另一个 StackOverflow 帖子中获取的以下代码:
private void Somewhere() {
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(AlwaysGoodCertificate);
}
private static bool AlwaysGoodCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors) {
return true;
}
问题是服务器从不验证证书,并失败并出现上述错误。有谁知道我应该怎么做?
我应该提一下,几周前我和一位同事进行了测试,它与我上面写的类似的东西工作正常。我们发现的唯一“主要区别”是我使用的是 Windows 7,而他使用的是 Windows XP。这会改变什么吗?
答:
您可以尝试安装演示证书(一些 ssl 提供商免费提供一个月),以确定问题是否与证书有效性有关。
评论
您遇到的问题是 aspNet 用户无权访问证书。您必须使用 winhttpcertcfg.exe 授予访问权限
有关如何设置的示例,请参阅:http://support.microsoft.com/kb/901183
在步骤 2 下的详细信息
编辑:在较新版本的IIS中,此功能内置于证书管理器工具中 - 可以通过右键单击证书并使用管理私钥的选项来访问。更多详情请见:https://serverfault.com/questions/131046/how-to-grant-iis-7-5-access-to-a-certificate-in-certificate-store/132791#132791
评论
该错误是通用的,SSL/TLS 协商失败的原因有很多。最常见的是服务器证书无效或过期,您通过提供自己的服务器证书验证挂钩来解决这个问题,但这不一定是唯一的原因。服务器可能需要相互身份验证,它可能配置了客户端不支持的密码套件,它的时间偏差太大,握手无法成功,以及更多原因。
最好的解决方案是使用 SChannel 故障排除工具集。SChannel 是负责 SSL 和 TLS 的 SSPI 提供程序,客户端将使用它进行握手。查看 TLS/SSL 工具和设置。
另请参阅如何启用 Schannel 事件日志记录。
评论
Schannel event logging
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL
EventLogging
1
Event Viewer
Schannel
我终于找到了答案(我没有注意到我的来源,但它来自搜索);
虽然代码在 Windows XP 中有效,但在 Windows 7 中,您必须在开头添加以下内容:
// using System.Net;
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
// Use SecurityProtocolType.Ssl3 if needed for compatibility reasons
现在,它运行良好。
补遗
正如罗宾·弗伦奇(Robin French)所提到的;如果您在配置 PayPal 时遇到此问题,请注意,从 2018 年 12 月 3 日开始,它们将不支持 SSL3。您需要使用 TLS。这是关于它的PayPal页面。
评论
System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;
另一种可能性是包装盒上的证书导入不正确。确保选中“圈出”复选框。最初我没有这样做,所以代码要么超时,要么抛出相同的异常,因为找不到私钥。
评论
正如你所知道的,发生这种情况的原因有很多。以为我会添加我遇到的原因......
如果将值设置为 ,则会引发异常。下面是我拥有的代码......(除了没有为超时值硬编码,我有一个无意中设置为 的参数)。WebRequest.Timeout
0
0
0
WebRequest webRequest = WebRequest.Create(@"https://myservice/path");
webRequest.ContentType = "text/html";
webRequest.Method = "POST";
string body = "...";
byte[] bytes = Encoding.ASCII.GetBytes(body);
webRequest.ContentLength = bytes.Length;
var os = webRequest.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
os.Close();
webRequest.Timeout = 0; //setting the timeout to 0 causes the request to fail
WebResponse webResponse = webRequest.GetResponse(); //Exception thrown here ...
评论
如果服务器对 HTTP 请求返回 HTTP 401 未经授权的响应,则可能会出现“请求已中止:无法创建 SSL/TLS 安全通道”异常。
您可以通过为客户端应用程序启用跟踪级别 System.Net 日志记录来确定是否正在发生这种情况,如本答案中所述。
一旦日志记录配置就位,请运行应用程序并重现错误,然后在日志记录输出中查找如下所示的行:
System.Net Information: 0 : [9840] Connection#62912200 - Received status line: Version=1.1, StatusCode=401, StatusDescription=Unauthorized.
在我的情况下,我未能设置服务器期望的特定 cookie,导致服务器以 401 错误响应请求,这反过来又导致“无法创建 SSL/TLS 安全通道”异常。
评论
2 errors in 2 months
我在尝试点击 https://ct.mob0.com/Styles/Fun.png 时遇到了这个问题,这是CloudFlare在其CDN上分发的图像,支持SPDY和奇怪的重定向SSL证书等疯狂的东西。
我没有像 Simons 回答那样指定 Ssl3,而是能够像这样通过下降到 Tls12 来修复它:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
new WebClient().DownloadData("https://ct.mob0.com/Styles/Fun.png");
评论
只要这是一个相对“实时”的链接,我想我会添加一个新选项。这种可能性是,由于贵宾犬攻击的问题,该服务不再支持 SSL 3.0。查看谷歌关于此的声明。我同时在多个 Web 服务中遇到了这个问题,并意识到一定发生了什么事。我切换到 TLS 1.2,一切又恢复了正常。
http://googleonlinesecurity.blogspot.com/2014/10/this-poodle-bites-exploiting-ssl-30.html
经过长时间的相同问题,我发现运行客户端服务的 ASP.NET 帐户无权访问证书。我通过进入运行 Web 应用程序的 IIS 应用程序池,进入“高级设置”,然后将 Identity 更改为帐户来修复它。LocalSystem
NetworkService
更好的解决方案是让证书使用默认帐户,但这适用于快速功能测试。NetworkService
评论
对我来说,问题是我尝试在 IIS 上部署为 Web 服务,我在服务器上安装了证书,但运行 IIS 的用户对证书没有正确的权限。
如何授予 ASP.NET 对证书存储中证书中的私钥的访问权限?
评论
这发生在我在一个站点上,结果证明它只有可用的 RC4 密码。在之前加固服务器的努力中,我禁用了 RC4 密码,一旦我重新启用它,问题就解决了。
评论
我整天都在为这个问题而苦苦挣扎。
当我使用 .NET 4.5 创建一个新项目时,我终于让它工作了。
但是,如果我降级到 4.0,我又会遇到同样的问题,并且对于该项目来说是不可逆转的(即使我再次尝试升级到 4.5)。
奇怪的是,没有其他错误消息,但出现了“请求已中止:无法创建SSL / TLS安全通道”
评论
最初的答案没有的东西。我添加了更多代码以使其防弹。
ServicePointManager.Expect100Continue = true;
ServicePointManager.DefaultConnectionLimit = 9999;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
评论
Tls and Tls11
SSL v2 unsecure, SSL v3 is insecure when used with HTTP (the POODLE attack), TLS v1.0, TLS v1.1 obsoletes
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
该错误的另一个可能原因是客户端 PC 的配置cipher_suites值与服务器配置为愿意并能够接受的值不匹配。在这种情况下,当客户端在其初始 SSL 握手/协商“Client Hello”消息中发送它能够接受的 cipher_suites 值列表时,服务器会发现提供的值都不可接受,并且可能会返回“Alert”响应,而不是继续执行 SSL 握手的“Server Hello”步骤。The request was aborted: Could not create SSL/TLS secure channel
若要调查这种可能性,可以下载 Microsoft 消息分析器,并使用它来对 SSL 协商运行跟踪,当您尝试与服务器(在 C# 应用中)建立 HTTPS 连接但失败时,该协商将发生跟踪。
如果能够从其他环境(例如您提到的 Windows XP 计算机)成功建立 HTTPS 连接,或者可能通过在不使用操作系统密码套件设置的非 Microsoft 浏览器(如 Chrome 或 Firefox)中点击 HTTPS URL),请在该环境中运行另一个消息分析器跟踪,以捕获 SSL 协商成功时发生的情况。
希望您能看到两条客户端 Hello 消息之间的一些差异,这将使您能够准确确定失败的 SSL 协商导致其失败的原因。然后,您应该能够对 Windows 进行配置更改,使其成功。IISCrypto 是一个很好的工具(即使对于客户端 PC,尽管名称为“IIS”)。
以下两个 Windows 注册表项控制你的电脑将使用的cipher_suites值:
- HKLM\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002
- HKLM\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\00010002
以下是我如何调查和解决此类问题的完整文章: http://blog.jonschneider.com/2016/08/fix-ssl-handshaking-error-in-windows.htmlCould not create SSL/TLS secure channel
评论
就我而言,此异常的根源是,在代码中的某个时刻调用了以下内容:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
这真的很糟糕。它不仅指示 .NET 使用不安全的协议,而且还会影响之后在 appdomain 中发出的每个新 WebClient(和类似)请求。(请注意,传入的 Web 请求在 ASP.NET 应用中不受影响,但新的 WebClient 请求(例如与外部 Web 服务通信)会受到影响)。
就我而言,实际上并不需要它,所以我可以删除该语句,所有其他 Web 请求又开始正常工作。根据我在其他地方的阅读,我学到了一些东西:
- 这是 appdomain 中的全局设置,如果您有并发活动,则无法可靠地将其设置为一个值,执行操作,然后将其设置回去。另一个操作可能会发生在该小窗口期间并受到影响。
- 正确的设置是将其保留为默认值。这允许 .NET 随着时间的推移和升级框架继续使用最安全的默认值。将其设置为 TLS12(在撰写本文时是最安全的)现在可以使用,但在 5 年后可能会开始引起神秘问题。
- 如果确实需要设置值,则应考虑在单独的专用应用程序或 appdomain 中执行此操作,并找到一种方法在它与主池之间进行通信。由于它是单个全局值,因此尝试在繁忙的应用池中管理它只会导致麻烦。这个答案:https://stackoverflow.com/a/26754917/7656 通过自定义代理提供了一种可能的解决方案。(请注意,我没有亲自实现它。
评论
如果客户端是 Windows 计算机,则可能的原因可能是未激活服务所需的 tls 或 ssl 协议。
这可以设置在:
控制面板 -> 网络和互联网 -> 互联网选项 ->高级
向下滚动设置到“安全”,然后在
- 使用 SSL 2.0
- 使用 SSL 3.0
- 使用 TLS 1.0
- 使用 TLS 1.1
- 使用 TLS 1.2
评论
我遇到了这个问题,因为我的web.config有:
<httpRuntime targetFramework="4.5.2" />
而不是:
<httpRuntime targetFramework="4.6.1" />
评论
就我而言,当 Windows 服务尝试连接到 Web 服务时,我遇到了这个问题。在Windows事件中,我终于发现了一个错误代码。
引发事件 ID 36888 (Schannel):
生成了以下致命警报:40。内部错误状态为 808。
最后,它与Windows修补程序有关。就我而言:KB3172605和KB3177186
vmware 论坛中建议的解决方案是在 Windows 中添加一个注册表项。添加以下注册表后,一切正常。
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\KeyExchangeAlgorithms\Diffie-Hellman]
“ClientMinKeyBitLength”=dword:00000200
显然,这与客户端HTTPS握手中的缺失值有关。
列出 Windows 修补程序:
wmic qfe list
解决方案主题:
https://communities.vmware.com/message/2604912#2604912
这个在MVC webclient中为我工作
public string DownloadSite(string RefinedLink)
{
try
{
Uri address = new Uri(RefinedLink);
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
using (WebClient webClient = new WebClient())
{
var stream = webClient.OpenRead(address);
using (StreamReader sr = new StreamReader(stream))
{
var page = sr.ReadToEnd();
return page;
}
}
}
catch (Exception e)
{
log.Error("DownloadSite - error Lin = " + RefinedLink, e);
return null;
}
}
评论
就我而言,运行应用程序的服务帐户无权访问私钥。一旦我给予了这个权限,错误就消失了
- MMC系列
- 证书
- 扩展到个人
- 选择证书
- 单击鼠标右键
- 所有任务
- 管理私钥
- 添加服务帐户用户
评论
默认的 .NET 使用 SSLv3 和 TLS。如果您正在访问 Apache 服务器,则有一个名为 config 变量的变量,默认为 TLSv1.2。您可以将 设置为使用 Web 服务器支持的适当协议,也可以更改 Apache 配置以允许所有协议,例如此 SSLProtocol
。ServicePointManager.SecurityProtocol
SSLProtocol
ServicePointManager.SecurityProtocol
all
评论
SSLv3
在 .NET 4.5 中,这个问题的解决方案是
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
如果没有 .NET 4.5,请使用
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
评论
ServicePointManager.SecurityProtocol = DirectCast(3072, SecurityProtocolType)
如果要从 Visual Studio 运行代码,请尝试以管理员身份运行 Visual Studio。为我解决了这个问题。
评论
这对我来说已经解决了,将网络服务添加到权限中。 右键单击证书>“所有任务”>“管理私钥...”。>添加...>添加“网络服务”。
评论
我遇到了同样的问题,发现这个答案对我来说很有效。密钥是 3072。此链接提供有关“3072”修复的详细信息。
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
XmlReader r = XmlReader.Create(url);
SyndicationFeed albums = SyndicationFeed.Load(r);
评论
请确保在创建 HttpWebRequest 之前进行 ServicePointManager 设置,否则它将不起作用。
工程:
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12
| SecurityProtocolType.Ssl3;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://google.com/api/")
失败:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://google.com/api/")
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12
| SecurityProtocolType.Ssl3;
评论
我最近遇到了同样的问题。我的环境在 .NET 4.6.1 下运行,VB.NET。这就是我修复它的方式:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf util.ValidateServerCertificate)
和 util.ValidateServerCertificate 函数为:
Public Function ValidateServerCertificate(ByVal sender As Object, ByVal certificate As X509Certificate, ByVal chain As X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean
Return True
End Function
如果不想、不容易或无法快速修补代码,则可以在框架中强制 .NET 代码使用 TLS 1.2。
这不是我的应用程序,但它帮助我们修复了较旧的.NET 4.5应用程序(在Server 2008r2上运行)以再次与PayPal Payflow网关一起使用。他们必须在 18 年 6 月 25 日至 18 年 7 月 8 日之间开始在支付流网关回调上强制连接到 TLS 1.2。
详细信息: https://github.com/TheLevelUp/pos-tls-patcher 下载: https://github.com/TheLevelUp/pos-tls-patcher/releases
System.Net.WebException:请求已中止:无法创建 SSL/TLS 安全通道。
在我们的例子中,我们使用软件供应商,因此我们无权修改 .NET 代码。显然,除非有更改,否则 .NET 4 不会使用 TLS v 1.2。
我们的解决方法是将 SchUseStrongCrypto 密钥添加到注册表中。您可以将以下代码复制/粘贴到扩展名为 .reg 的文本文件中并执行它。它是我们解决问题的“补丁”。
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001
评论
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" -Name "SchUseStrongCrypto" -Value "1" -Type DWord
New-ItemProperty -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319" -Name "SchUseStrongCrypto" -Value "1" -Type DWord
这个问题可以有很多答案,因为它是关于一般错误消息的。我们在一些服务器上遇到了这个问题,但在我们的开发机器上没有。在拔掉大部分头发后,我们发现这是一个Microsoft的错误。
从本质上讲,MS 假设您想要更弱的加密,但操作系统已修补为仅允许 TLS 1.2,因此您会收到可怕的“请求已中止:无法创建 SSL/TLS 安全通道”。
有三个修复。
使用适当的更新修补操作系统:http://www.catalog.update.microsoft.com/Search.aspx?q=kb4458166
将设置添加到 app.config/web.config 文件(如上面的链接所述):
<runtime>
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false" />
</runtime>
- 添加另一个答案中已提及的注册表设置。
所有这些都在我发布的知识库文章中提到。
评论
没有一个答案对我有用。
这是有效的:
而不是像这样初始化我:X509Certifiacte2
var certificate = new X509Certificate2(bytes, pass);
我是这样做的:
var certificate = new X509Certificate2(bytes, pass, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
注意 !!X509KeyStorageFlags.Exportable
我没有更改代码的其余部分(本身):WebRequest
// I'm not even sure the first two lines are necessary:
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
request = (HttpWebRequest)WebRequest.Create(string.Format("https://{0}.sii.cl/cvc_cgi/dte/of_solicita_folios", server));
request.Method = "GET";
request.Referer = string.Format("https://hercules.sii.cl/cgi_AUT2000/autInicio.cgi?referencia=https://{0}.sii.cl/cvc_cgi/dte/of_solicita_folios", servidor);
request.UserAgent = "Mozilla/4.0";
request.ClientCertificates.Add(certificate);
request.CookieContainer = new CookieContainer();
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
// etc...
}
事实上,我什至不确定前两行是否必要......
评论
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
使用这条线对我有用。
我有证书在商店里,在档案中。我尝试连接文件并收到此错误消息。当我在商店里使用那个时,它起作用了。我最好的猜测是,当我想使用存档的证书时,由于证书在存储中而产生了某种冲突。 (同一台机器上的不同服务使用了商店中的证书,我使用存档的证书开发了不同的服务。在测试之前,在开发上就像一个魅力)。
对于大多数人来说,得票最高的答案可能就足够了。但是,在某些情况下,即使在强制使用 TLS 1.2 后,您仍可能会继续收到“无法创建 SSL/TLS 安全通道”错误。如果是这样,您可能需要查阅这篇有用的文章,了解其他故障排除步骤。总而言之:与TLS / SSL版本问题无关,客户端和服务器必须就“密码套件”达成一致。在 SSL 连接的“握手”阶段,客户端将列出其支持的密码套件,以便服务器根据自己的列表进行检查。但是在某些Windows机器上,某些通用密码套件可能已被禁用(似乎是由于善意地试图限制攻击面),从而降低了客户端和服务器就密码套件达成一致的可能性。如果他们不同意,则可能会在事件查看器中看到“致命警报代码 40”,并在 .NET 程序中看到“无法创建 SSL/TLS 安全通道”。
上述文章介绍了如何列出计算机的所有可能支持的密码套件,并通过 Windows 注册表启用其他密码套件。若要帮助检查客户端上启用了哪些密码套件,请尝试访问 MSIE 中的此诊断页。(使用 System.Net 跟踪可能会给出更明确的结果。要检查服务器支持哪些密码套件,请尝试使用此在线工具(假设服务器可通过 Internet 访问)。毋庸置疑,必须谨慎进行注册表编辑,尤其是在涉及网络的情况下。(您的计算机是远程托管的 VM 吗?如果要中断网络,是否可以访问 VM?
在我公司的案例中,我们通过注册表编辑启用了几个额外的“ECDHE_ECDSA”套件,以解决眼前的问题并防范未来的问题。但是,如果您不能(或不会)编辑注册表,那么就会想到许多解决方法(不一定漂亮)。例如:您的 .NET 程序可以将其 SSL 流量委托给单独的 Python 程序(该程序本身可能有效,原因与 Chrome 请求可能成功的原因相同,而 MSIE 请求在受影响的计算机上失败)。
评论
我在通过命令行应用程序将视频上传到 Wistia 时遇到了这个问题。我们的系统管理员通过使用 SSL 实验室扫描中列出的 IIScrypto 启用其他密码套件来解决此问题 upload.wistia.com
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x9e) DH 2048 位 FS 128 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x9f) DH 2048 位 FS 256
注意:这里得票最高的几个答案建议设置,但 Microsoft 明确建议不要这样做。下面,我将介绍此问题的典型原因以及解决该问题的最佳实践。ServicePointManager.SecurityProtocol
此问题的最大原因之一是活动的 .NET Framework 版本。.NET Framework 运行时版本会影响默认情况下启用的安全协议。
- 在 ASP.NET 网站中,框架运行时版本通常在 web.config 中指定。(见下文)
- 在其他应用中,运行时版本通常是为其生成项目的版本,无论它是否在具有较新 .NET 版本的计算机上运行。
似乎没有任何关于它在不同版本中具体工作方式的权威文档,但似乎默认值或多或少地确定如下:
框架版本 | 默认协议 |
---|---|
4.5 及更早版本 | SSL 3.0、TLS 1.0 |
4.6.x | TLS 1.0、1.1、1.2、1.3 |
4.7+ | 系统 (OS) 默认值 |
对于旧版本,您的里程可能会因系统上安装的 .NET 运行时而异。例如,可能存在以下情况:您使用的是非常旧的框架,并且不支持 TLS 1.0,或者不支持使用 4.6.x 和 TLS 1.3。
Microsoft 的文档强烈建议使用 4.7+,系统默认值:
我们建议您:
- 面向应用上的 .NET Framework 4.7 或更高版本。 在 WCF 应用上面向 .NET Framework 4.7.1 或更高版本。
- 不要指定 TLS 版本。配置代码,让 OS 决定 TLS 版本。
- 执行彻底的代码审核,以验证您未指定 TLS 或 SSL 版本。
对于 ASP.NET 站点:检查元素中的版本,因为这(如果存在)决定了站点实际使用的运行时:targetFramework
<httpRuntime>
<httpRuntime targetFramework="4.5" />
更好:
<httpRuntime targetFramework="4.7" />
评论
设置方法
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
似乎没问题,因为 Tls1.2 是安全协议的最新版本。但我决定更深入地研究并回答我们是否真的需要硬编码。
规格:Windows Server 2012R2 x64。
从互联网上得知.默认情况下,NetFramework 4.6+ 必须使用 Tls1.2。但是当我将我的项目更新到 4.6 时,什么也没发生。 我发现了一些信息,告诉我需要手动进行一些更改才能默认启用 Tls1.2
但是建议的 Windows 更新不适用于 R2 版本
但对我有帮助的是向注册表添加 2 个值。您可以使用下一个 PS 脚本,以便自动添加它们
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
这就是我一直在寻找的。但是我仍然无法回答为什么 NetFramework 4.6+ 不设置这个......协议值自动?
评论
另一种可能性是正在执行的代码没有所需的权限。
就我而言,我在使用 Visual Studio 调试器测试对 Web 服务的调用时出现此错误。Visual Studio 未以管理员身份运行,这导致了此异常。
这个答案都不适合我,Google Chrome 和 Postman 可以工作并握手服务器,但 IE 和 .NET 不起作用。在 Google Chrome 的“安全”选项卡>连接中,显示使用带有 P-256 的ECDHE_RSA进行加密和身份验证AES_256_GCM密码套件与服务器握手。
我在 Windows Server 2012 R2 上安装了 IIS Crypto 并在密码套件列表中,我找不到带有 P-256 和AES_256_GCM密码套件的ECDHE_RSA。然后我将Windows更新到最新版本,但问题没有解决。最后,经过搜索,我了解到Windows Server 2012 R2无法正确支持GSM,并将我的服务器更新到Windows Server 2016,我的问题解决了。
我在 Windows 2008 Server 上的 .NET 4.5.2 Winform 应用程序上遇到了同样的错误。
我尝试了以下修复程序:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls1|SecurityProtocolType.Tls11| SecurityProtocolType.Tls12;
但这并没有奏效,错误的发生次数仍然存在。
根据上面的答案之一,是否必须将 SchUseStrongCrypto 密钥覆盖到注册表中。如果我设置这个键,有什么副作用吗?
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001
这样做帮助了我:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
从注册表中删除此选项在Windows Server 2012中帮助了我 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\KeyExchangAlgorithms
对于 SOAP/WCF 用户,当服务器拒绝 WS-Security 配置时,也会发生此错误。客户端收到的错误信息非常模糊,但服务器管理员可能能够确定原因。
例如,在 UsernameToken 配置文件下,由于格式错误、不是 UTC 或服务器时间不匹配,消息被视为过期时间不是有效的 ISO 8601 日期时间。<wsu:Created>
<wsse:UsernameToken wsu:Id="Example-1">
<wsse:Username> ... </wsse:Username>
<wsse:Password Type="..."> ... </wsse:Password>
<wsse:Nonce EncodingType="..."> ... </wsse:Nonce>
<wsu:Created>2021-01-31T19:00:00.0000000Z</wsu:Created>
</wsse:UsernameToken>
在调用 HTTPS URL(适用于 .NET Framework 4.5)之前,请尝试添加以下行:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
上面的大多数答案都提到了会话算法或密钥交换算法。
就我而言,两者都没问题,问题出在服务器的证书哈希算法中,该算法未在客户端的 PC 上启用。
我想通了,在我的应用程序的配置中添加了一个部分。
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.Net">
<listeners>
<add name="System.Net" />
</listeners>
</source>
<source name="System.Net.Sockets">
<listeners>
<add name="System.Net" />
</listeners>
</source>
<source name="System.Net.Cache">
<listeners>
<add name="System.Net" />
</listeners>
</source>
</sources>
<sharedListeners>
<add
name="System.Net"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="System.Net.trace.log"
/>
</sharedListeners>
<switches>
<add name="System.Net" value="Verbose" />
<add name="System.Net.Sockets" value="Verbose" />
<add name="System.Net.Cache" value="Verbose" />
</switches>
</system.diagnostics>
然后日志中的错误使我找到了这个解决方案
我知道这是迟到的答案,但是当我尝试从win server 2016 R2(客户端)调用API(托管在win server 2012上)时,我遇到了同样的问题
经过大量调查,该问题与操作系统级别的握手问题有关,特别是主机服务器不支持来自客户端的密码列表。
当我使用 Wireshark 跟踪连接时,我了解了这个问题,我发现发送的密码不受支持。
Window Server 2012 R2 对可能导致 TLS/SSL 握手的新密码的支持有限。
当我看到此错误时,开始是“从远程端点收到致命警报。TLS 协议定义的致命警报代码在事件查看器 (事件查看器 >> 管理事件>>自定义视图))
就我而言,我在 Visual Studio 2022 下运行。我一次又一次地收到这个错误。通过代码,我看到它很好地检索了证书。安全性设置为 TLS1.2,上面两个答案。无论出于何种原因,以管理员身份运行 Visual Studio 使其正常工作! 也许有人可以向我解释代码如何从商店中检索证书。我可以看到它和所有的属性。为什么以这个世界的名义,除非我在管理模式下运行 VS,否则它不会处理请求???
经过几天的拔掉我遗漏的头发,我们解决了这个问题。我尝试了这篇文章中建议的所有内容,但没有任何效果。对于我们来说,我们有一个基本的 .Net Framework 4.8 控制台应用,在客户的 Windows VM 上运行。与我们通信的本地服务器要求关闭 SSL 证书验证。我们的一个人发现服务器要求我们使用 TLS 1.0,并且在 VM 的注册表设置中,TLS 1.0 被禁用。一旦我们启用了它,它就起作用了。我还需要添加以下两行,如上面多次提到的那样:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
评论
我们在客户端 Windows Server 2012R2 中遇到了同样的问题。 错误 40 表示客户端和服务器不同意要使用的密码套件。 在大多数情况下,服务器需要客户端无法识别的密码套件。
如果无法修改服务器设置,解决方案是以这种方式将那些“缺失”的密码套件添加到客户端:
- 首先,转到 SSLLabs SSL Labs
- 输入您遇到连接问题的站点/api 的 URL
- 等待几分钟,直到测试完成
- 转到“密码套件”部分并仔细阅读 TLS 1.3 / TLS 1.2
- 在那里,您将找到服务器接受的密码套件
- 现在在您的 Windows 服务器中,转到 Regedit
- 打开钥匙:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL
- 在那里,您会发现 2 个文件夹:
00010002 -->TLS 1.2 and 00010003 --> TLS 1.3
- 现在,编辑 Functions 键,并添加服务器所需的套件
- 在我们的例子中,我们需要添加到文件夹
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
00010002
如果您已经拥有这个
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
| SecurityProtocolType.Tls13
| SecurityProtocolType.Tls12
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls;
在您的代码中,您或您的客户仍然在这里收到此错误,我发现这对我的公司有用:
我们看到越来越多的错误来自较新版本的Windows操作系统,我相信原因是Microsoft开始在最新的Windows更新中停用较旧的TLS版本,并且Windows操作系统不再支持它们。上面的枚举似乎是在协商安全协议的套接字握手期间使用的。通过像这样设置枚举,您错误地宣传了对操作系统不支持的安全协议的支持。当打开安全通道并在客户端和服务器之间协商不支持的协议之一时,最终会出现上述错误。从 .net framework 4.7 开始,不应显式设置安全协议并保留其默认值,该默认值实际上是操作系统支持的一组协议。这样,您就不会协商不支持的协议,也不会得到我们正在谈论的错误。
这些步骤对我有用,适用于 Windows Server 2012 R2。
- 首先安装任何挂起的 Windows 更新,然后重新启动服务器。
- 转到 SSLLabs https://www.ssllabs.com/ssltest/analyze.html
- 输入您连接时遇到问题的站点/api 的 url,请等待 距离测试完成还需要一段时间
- 转到“密码套件”部分并仔细阅读 TLS 1.3 / TLS 1.2。在那里,您将找到服务器接受的密码套件。
- 从 https://www.nartac.com/Products/IISCrypto/Download 下载 IISCrypto GUI 工具
- 启用 TLS 1.2(如果已禁用)。(使用 IISCrypto GUI 工具)
- 启用您在第 5 点中找到的其他/缺失密码套件 (使用 IISCrypto GUI 工具)。
- 重新启动服务器。
评论
The request was aborted: Could not create SSL/TLS secure channel