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

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

我们知道服务器没有有效的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。这会改变什么吗?


当前回答

In my case, I was running under Visual Studio 2022. Time and time again I was getting this error. Going through the code I saw that it retrieved the certificate just fine. Security was set to TLS1.2, both answers above. For whatever reason, running Visual Studio as Administrator made it work! Maybe someone can explain to me how the code retrieved the certificate from the store just fine. I could see it and all the properties. Why in the name of this world would it not process the request unless I run VS in admin mode???

其他回答

在这个问题上花了很多时间后,我发现ASP。运行客户端服务的NET帐户没有访问证书的权限。我通过进入web应用程序运行的IIS应用程序池,进入高级设置,并将身份从NetworkService更改为LocalSystem帐户来修复它。

更好的解决方案是让证书与默认的NetworkService帐户一起工作,但这适用于快速功能测试。

对我来说,问题是我试图将IIS作为web服务部署在服务器上,我在服务器上安装了证书,但运行IIS的用户对证书没有正确的权限。

如何给ASP。NET访问证书存储中的证书中的私钥?

设置方法

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12

看起来还可以,因为Tls1.2是最新版本的安全协议。但我决定深入研究,并回答我们是否真的需要硬编码它。

规格:Windows Server 2012R2 x64。

从互联网上得知,. net framework 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

这正是我想要的。但是我仍然不能回答为什么NetFramework 4.6+没有设置这个问题…自动协议值?

如果服务器对HTTP请求返回HTTP 401未授权响应,则会出现“请求已终止:无法创建SSL/TLS安全通道”异常。

您可以通过打开跟踪级系统来确定是否发生这种情况。Net日志记录用于客户端应用程序,如本回答中所述。

一旦日志配置就绪,运行应用程序并重现错误,然后在日志输出中查找如下一行:

System.Net Information: 0 : [9840] Connection#62912200 - Received status line: Version=1.1, StatusCode=401, StatusDescription=Unauthorized.

在我的情况下,我未能设置服务器所期望的特定cookie,导致服务器以401错误响应请求,从而导致“无法创建SSL/TLS安全通道”异常。

没有一个答案对我有用。

这是有效的方法:

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

   var certificate = new X509Certificate2(bytes, pass);

我是这样做的:

   var certificate = new X509Certificate2(bytes, pass, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);

注意X509KeyStorageFlags。出口! !

我没有改变其余的代码(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...
}

事实上,我甚至不确定前两行是否有必要……