请求已中止:无法创建SSL/TLS安全通道

Sim*_*gré 349 c# asp.net httpwebrequest windows-7 windows-8

WebRequest由于此错误消息,我们无法连接到HTTPS服务器:

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;
}
Run Code Online (Sandbox Code Playgroud)

问题是服务器永远不会验证证书并因上述错误而失败.有谁知道我该怎么办?


我应该提到一位同事和我几周前进行了测试,并且它与我上面写的内容类似.我们发现的唯一"主要差异"是我使用的是Windows 7并且他使用的是Windows XP.这有什么改变吗?

Sim*_*gré 508

我终于找到了答案(我没有注意到我的来源,但它来自搜索);

虽然代码适用于Windows XP,但在Windows 7中,您必须在开头添加此代码:

// using System.Net;
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
// Use SecurityProtocolType.Ssl3 if needed for compatibility reasons
Run Code Online (Sandbox Code Playgroud)

现在,它完美无缺.


附录

如罗宾法国人所说; 如果您在配置PayPal时遇到此问题,请注意,从2018年12月开始,他们不支持SSL3.您需要使用TLS.这是关于它的Paypal页面.

  • SSLv3已有18年历史,现在很容易受到POODLE攻击 - 正如@LoneCoder建议的那样,SecurityProtocolType.Tls12是SecurityProtocolType.Ssl3的合适替代品. (24认同)
  • 另见[this](/sf/answers/3027171381/).您不需要将其专门设置为单一类型,您也可以简单地附加.`System.Net.ServicePointManager.SecurityProtocol | = System.Net.SecurityProtocolType.Tls12;` (11认同)
  • 转到SecurityProtocolType.Tls12实际上为我解决了这个问题.请参阅下面的答案. (4认同)
  • SecurityProtocolType.Tls实际上可能是一个更好的选择,直到找到漏洞为止(并非所有站点在写入时都支持Tls12) (4认同)
  • PayPal已将2017年6月30日的日期设置为禁用SSL3并实施TLS1.2.它已经应用在他们的沙箱环境中https://www.paypal-knowledge.com/infocenter/index?page=content&widgetview=true&id=FAQ1914&viewlocale=en_US (3认同)
  • `ServicePointManager`是`System.Net`命名空间中的一个类,`Expect100Continue`和`SecurityProtocol`是该类的静态属性.没有`using`指令,你可以通过`System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;`来完成这个任务. (2认同)
  • 您可以使用 HttpWebRequest 向此 url 发送 GET 请求:https://www.ssllabs.com/ssltest/viewMyClient.html 并将响应正文保存到磁盘,然后在浏览器中打开此文件。它会告诉您所选择的协议版本(SecurityProtocolType 具有 FlagsAttribute 属性)以及有关您的 Web 客户端的许多其他安全详细信息。 (2认同)
  • 这有效,但在执行 Web 请求之前设置 ServicePointManager 设置非常重要。IE ServicePointManager 代码应位于代码顶部才能工作。 (2认同)
  • 此更改是静态的且是全局的,因此您只需要执行一次即可,而不必为每个请求执行一次-理想情况下是在启动类中。否则,您可能会遇到奇怪的行为。我仅在第一个请求中看到此错误,随后的请求都可以。这是因为在上述步骤之前已建立HttpWebRequest,所以新初始化的HttpWebRequest直到第二次运行才适合新协议。 (2认同)
  • 您不需要设置“ServicePointManager.Expect100Continue = true;”。默认情况下启用它([请参阅此处](https://docs.microsoft.com/en-us/dotnet/api/system.net.servicepointmanager.expect100continue?view=netframework-4.8#property-value))。 (2认同)
  • 应当指出,Microsoft [强烈建议您不要这样做](https://docs.microsoft.com/zh-cn/dotnet/framework/network-programming/tls)。如果您看到此问题,则很可能是由于使用了旧版本的.NET框架。我已经[添加了答案](/sf/answers/4073719121/)对此进行了更详细的介绍。 (2认同)

小智 115

在.NET 4.5中解决这个问题的方法是

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Run Code Online (Sandbox Code Playgroud)

如果您没有.NET 4.5,请使用

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!我需要使用.net 4.0并且不知道如何解决这个问题.这似乎在这里工作.:) (6认同)
  • 不适用于 Windows Server 2008R2(也可能适用于 2012) (3认同)
  • 对于 VB 类型(因为这个答案出现在 Google 中),等效的代码是`ServicePointManager.SecurityProtocol = DirectCast(3072, SecurityProtocolType)` (2认同)

hog*_*h45 80

确保在HttpWebRequest建立之前进行了ServicePointManager设置,否则它将无法工作.

作品:

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

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://google.com/api/")
Run Code Online (Sandbox Code Playgroud)

失败:

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://google.com/api/")

        ServicePointManager.Expect100Continue = true;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
               | SecurityProtocolType.Tls11
               | SecurityProtocolType.Tls12
               | SecurityProtocolType.Ssl3;
Run Code Online (Sandbox Code Playgroud)

  • 您上面提到的Works和Fails之间的区别是什么? (3认同)
  • 太棒了 我的请求仅在第二次尝试后才起作用,这没有意义,然后我看到您的帖子,在请求之前移动了安全协议,并进行了修复。谢谢@ hogarth45 (3认同)
  • 确切地!当我在创建请求之前放置 ServicePointManager 时,它对我有用,谢谢,你救了我的一天。 (3认同)
  • 在我们的例子中,请求第一次失败,后来又成功了。正是因为这个答案中所说的原因! (2认同)
  • 我不敢相信像初始化顺序这样愚蠢的事情为我解决了这个问题。SMH。谢谢@horgath45! (2认同)

JLR*_*she 35

注意:这里有几个投票最高的答案建议设置ServicePointManager.SecurityProtocol,但微软明确建议要这样做。下面,我将介绍此问题的典型原因以及解决此问题的最佳做法。

此问题的最大原因之一是活动的 .NET Framework 版本。.NET 框架运行时版本会影响默认启用的安全协议。

  • 在 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 版本。配置您的代码,让操作系统决定 TLS 版本。
  • 执行彻底的代码审计以验证您没有指定 TLS 或 SSL 版本。

对于 ASP.NET 站点:检查元素中的targetFramework版本<httpRuntime>,因为这(如果存在)确定您的站点实际使用哪个运行时:

<httpRuntime targetFramework="4.5" />
Run Code Online (Sandbox Code Playgroud)

更好的:

<httpRuntime targetFramework="4.7" />
Run Code Online (Sandbox Code Playgroud)


Avi*_*tus 31

您遇到的问题是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

  • 在Windows 7及更高版本中,证书必须位于本地计算机的存储区而不是当前用户才能"管理私钥" (2认同)
  • 是的,这是我的问题。使用 mmc.exe,添加证书管理单元(对我来说,我选择了“本地计算机”)。右键证书,所有任务,管理私钥。添加“每个人”(对于本地开发人员来说这是最简单的 - 产品显然需要您的显式 IIS 网站应用程序池/用户) (2认同)

Rem*_*anu 27

该错误是通用的,并且SSL/TLS协商可能失败的原因有很多.最常见的是无效或过期的服务器证书,您通过提供自己的服务器证书验证挂钩来解决这个问题,但不一定是唯一的原因.服务器可能需要相互身份验证,它可能配置了客户端不支持的密码套件,它可能有一个时间漂移太大,握手成功和更多的原因.

最佳解决方案是使用SChannel故障排除工具集.SChannel是负责SSL和TLS的SSPI提供程序,您的客户端将使用它进行握手.看看TLS/SSL工具和设置.

另请参阅如何启用Schannel事件日志记录.


Bry*_*end 27

我有这个问题试图点击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");
Run Code Online (Sandbox Code Playgroud)


sim*_*ood 26

设置方法

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
Run Code Online (Sandbox Code Playgroud)

看起来没问题,因为 Tls1.2 是最新版本的安全协议。但我决定深入研究并回答我们是否真的需要对其进行硬编码。

规格:Windows Server 2012R2 x64。

从互联网上得知 .NetFramework 4.6+ 必须默认使用 Tls1.2。但是当我将项目更新到 4.6 时,什么也没发生。我发现一些信息告诉我需要手动进行一些更改以默认启用 Tls1.2

https://support.microsoft.com/en-in/help/3140245/update-to-enable-tls-1-1-and-tls-1-2-as-default-secure-protocols-in-wi

但是建议的 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
Run Code Online (Sandbox Code Playgroud)

这就是我一直在寻找的东西。但是我仍然无法回答为什么 NetFramework 4.6+ 不自动设置这个 ...Protocol 值的问题?


Nic*_*tch 20

经过长时间的同一个问题后,我发现运行客户端服务的ASP.NET帐户无法访问证书.我通过进入Web应用程序运行的IIS应用程序池,进入高级设置,并将身份更改为LocalSystem帐户来修复它NetworkService.

更好的解决方案是使证书使用默认NetworkService帐户,但这适用于快速功能测试.

  • 这个答案应该有更多的选票.经过一周的研究,这是唯一对我有用的解决方案.谢谢!! (3认同)

Spo*_*com 15

原始答案没有的东西.我添加了一些代码以使其成为防弹.

ServicePointManager.Expect100Continue = true;
        ServicePointManager.DefaultConnectionLimit = 9999;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
Run Code Online (Sandbox Code Playgroud)

  • 我不建议添加SSL3协议. (7认同)

She*_*ock 13

另一种可能性是在盒子上输入不正确的证书.确保选中环绕的复选框.最初我没有这样做,因此代码要么超时要么抛出相同的异常,因为无法找到私钥.

证书输入对话框


Jon*_*der 10

如果服务器正在向HTTP请求返回HTTP 401 Unauthorized响应,则"请求已中止:无法创建SSL/TLS安全通道"异常可能发生.

您可以通过为客户端应用程序启用跟踪级System.Net日志记录来确定是否发生这种情况,如本答案中所述.

一旦该日志记录配置到位,运行应用程序并重现错误,然后在日志记录输出中查找如下所示的行:

System.Net Information: 0 : [9840] Connection#62912200 - Received status line: Version=1.1, StatusCode=401, StatusDescription=Unauthorized.
Run Code Online (Sandbox Code Playgroud)

在我的情况下,我没有设置服务器期望的特定cookie,导致服务器响应401错误的请求,这反过来导致"无法创建SSL/TLS安全通道"异常.


Tyl*_*the 10

在我的例子中,这个异常的根源是在代码中的某个时刻调用了以下内容:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
Run Code Online (Sandbox Code Playgroud)

这真的很糟糕.它不仅指示.NET使用不安全的协议,而且这会影响您的appdomain中随后发出的每个新WebClient(和类似)请求.(请注意,传入的Web请求在您的ASP.NET应用程序中不受影响,但新的WebClient请求(例如与外部Web服务通信)都是如此.

在我的情况下,它实际上并不需要,所以我可以删除该语句,我的所有其他Web请求再次开始正常工作.基于我在其他地方的阅读,我学到了一些东西:

  • 这是您的appdomain中的全局设置,如果您有并发活动,则无法将其可靠地设置为一个值,执行操作,然后将其设置回来.在该小窗口期间可能发生另一个动作并受到影响.
  • 正确的设置是保留默认值.这允许.NET随着时间的推移继续使用任何最安全的默认值并升级框架.将它设置为TLS12(这是写作时最安全的)现在可以工作,但在5年内可能会开始引起神秘的问题.
  • 如果您确实需要设置值,则应考虑在单独的专用应用程序或应用程序域中执行此操作,并找到在它与主池之间进行通信的方法.因为它是一个单一的全局值,尝试在繁忙的应用程序池中管理它只会导致麻烦.这个答案:https: //stackoverflow.com/a/26754917/7656 通过自定义代理提供了一种可能的解决方案.(注意我没有亲自实现它.)

  • 与您的一般经验法则相反,我将添加一个例外,那就是您必须将其设置为TLS 1.2,而不是让默认设置运行。如果您使用的是.NET 4.6之前的框架,并且在服务器上禁用了不安全的协议(SSL或TLS 1.0 / 1.1),那么除非您将程序强制为TLS 1.2,否则您将无法发出请求。 (2认同)

Ter*_*lem 9

我有这个问题,因为我的web.config有:

<httpRuntime targetFramework="4.5.2" />
Run Code Online (Sandbox Code Playgroud)

并不是:

<httpRuntime targetFramework="4.6.1" />
Run Code Online (Sandbox Code Playgroud)


TCC*_*TCC 8

正如您所知,这可能有很多原因.以为我会添加我遇到的原因......

如果将值设置为WebRequest.Timeoutto 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 ...
Run Code Online (Sandbox Code Playgroud)

  • 哇!感谢您提到这一点。首先无法相信,首先尝试了很多不同的事情。然后,最后将超时设置为10秒,异常消失了!这是我的解决方案。(y) (2认同)

Jon*_*der 8

导致The request was aborted: Could not create SSL/TLS secure channel错误的另一个可能原因是客户端PC配置的cipher_suites值与服务器配置为愿意并且能够接受的值不匹配.在这种情况下,当您的客户端在其初始SSL握手/协商"客户端Hello"消息中发送它能够接受的cipher_suites值列表时,服务器会发现所提供的值都不可接受,并且可能返回"警报" "响应而不是继续进行SSL握手的"服务器Hello"步骤.

要研究这种可能性,您可以下载Microsoft消息分析器,并使用它来运行在您尝试无法与服务器建立HTTPS连接(在C#应用程序中)时发生的SSL协商的跟踪.

如果您能够从另一个环境(例如您提到的Windows XP计算机)成功建立HTTPS连接,或者可能通过在不使用操作系统密码套件设置的非Microsoft浏览器中访问HTTPS URL,例如Chrome或Firefox),在该环境中运行另一个Message Analyzer跟踪,以捕获SSL协商成功时发生的情况.

希望您会看到两个Client Hello消息之间的某些区别,这些消息将使您能够准确查明失败的SSL协商导致其失败的原因.然后,您应该能够对Windows进行配置更改,以使其成功. IISCrypto是一个很好用的工具(即使是客户端PC,尽管有"IIS"名称).

以下两个Windows注册表项控制您的PC将使用的cipher_suites值:

  • HKLM\SOFTWARE \政策\微软\加密\配置\ SSL\00010002
  • HKLM \系统\ CurrentControlSet \控制\加密\配置\本地\ SSL\00010002

以下是我如何调查并解决了这一问题的一个实例的完整Could not create SSL/TLS secure channel文章:http://blog.jonschneider.com/2016/08/fix-ssl-handshaking-error-in-windows.html

  • 切中要害地回答我的问题。有两件事帮助我找到了需要做出的改变。1. Web 服务器支持的密码套件:https://www.ssllabs.com/ssltest/ 2. 不同 Windows 版本支持的密码套件:https://docs.microsoft.com/en-us/windows/win32/ secauthn/schannel 密码套件 (3认同)

Aru*_*E S 8

这个在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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 会覆盖ServerCertificateValidationCallback引入新的安全漏洞吗? (2认同)

Mer*_*007 8

这样做对我有帮助:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Run Code Online (Sandbox Code Playgroud)


agh*_*ost 6

我整天都在努力解决这个问题.

当我使用.NET 4.5创建一个新项目时,我终于开始工作了.

但是,如果我降级到4.0,我又遇到了同样的问题,这对于那个项目是不可逆转的(即使我试图再次升级到4.5).

奇怪没有其他错误消息,但"请求已中止:无法创建SSL/TLS安全通道." 想出了这个错误

  • 这可能是因为不同的.NET版本支持不同的SSL/TLS协议版本.更多信息:http://blogs.perficient.com/microsoft/2016/04/tsl-1-2-and-net-support/ (5认同)

cno*_*nom 6

在客户端是Windows机器的情况下,可能的原因可能是服务所需的tls或ssl协议未被激活.

这可以设置为:

控制面板 - >网络和Internet - > Internet选项 - >高级

将设置滚动到"安全"并在两者之间进行选择

  • 使用SSL 2.0
  • 使用SSL 3.0
  • 使用TLS 1.0
  • 使用TLS 1.1
  • 使用TLS 1.2

在此输入图像描述


Din*_*jan 6

就我而言,运行该应用程序的服务帐户无权访问私钥。一旦获得此许可,错误就会消失

  1. 多媒体卡
  2. 证书
  3. 扩展到个人
  4. 选择证书
  5. 右键点击
  6. 所有任务
  7. 管理私钥


bpl*_*lus 6

如果要从Visual Studio运行代码,请尝试以管理员身份运行Visual Studio。为我解决了此问题。


Hey*_*ude 6

另一种可能性是正在执行的代码没有所需的权限。

就我而言,我在使用 Visual Studio 调试器测试对 Web 服务的调用时收到此错误。Visual Studio 未以管理员身份运行,这导致了此异常。


小智 5

我遇到了同样的问题,发现这个答案对我来说很有效。密钥是 3072。此链接提供了有关“3072”修复的详细信息。

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

XmlReader r = XmlReader.Create(url);
SyndicationFeed albums = SyndicationFeed.Load(r);
Run Code Online (Sandbox Code Playgroud)

在我的情况下,两个提要需要修复:

https://www.fbi.gov/feeds/fbi-in-the-news/atom.xml
https://www.wired.com/feed/category/gear/latest/rss
Run Code Online (Sandbox Code Playgroud)


cap*_*gon 5

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
Run Code Online (Sandbox Code Playgroud)

  • 这里 PS 用于快速编辑:`New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" -Name "SchUseStrongCrypto" -Value "1" -Type DWord` (3认同)
  • 这里 PS 用于快速编辑 2:`New-ItemProperty -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319" -Name "SchUseStrongCrypto" -Value "1" -Type DWord` (2认同)

spo*_*rts 5

没有一个答案对我有用。

这是有效的:

而不是X509Certifiacte2像这样初始化我:

   var certificate = new X509Certificate2(bytes, pass);
Run Code Online (Sandbox Code Playgroud)

我是这样做的:

   var certificate = new X509Certificate2(bytes, pass, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
Run Code Online (Sandbox Code Playgroud)

注意 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...
}
Run Code Online (Sandbox Code Playgroud)

事实上,我什至不确定前两行是否必要......


APW*_*APW 5

得票最多的答案可能会是足以让大多数人。但是,在某些情况下,即使强制实施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程序(由于在受影响的计算机上MSIE请求失败的情况下,Chrome请求可能会成功,因此它本身可能会起作用)。


小智 5

这个答案都对我不起作用,谷歌浏览器和邮递员工作并握手服务器,但 ie 和 .net 不工作。在谷歌浏览器中的安全选项卡> 连接显示使用ECDHE_RSA 与 P-256 和 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 并且我的问题解决了。


小智 5

终于为我找到了解决方案。

在调用 https url 之前尝试添加以下行(对于 .Net 框架 4.5):

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;


归档时间:

查看次数:

627349 次

最近记录:

5 年,11 月 前