由于以下错误消息,我们无法使用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。这会改变什么吗?
在我的例子中,当一个Windows服务试图连接到一个web服务时,我遇到了这个问题。在Windows事件中,我终于找到了一个错误代码。
事件ID 36888(通道)被引发:
The following fatal alert was generated: 40. The internal error state is 808.
最后,它与Windows热修复有关。在我的例子中是KB3172605和KB3177186
vmware论坛提出的解决方案是在windows中添加一个注册表项。添加以下注册表后,所有工作正常。
[HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ \控制SecurityProviders \ SCHANNEL \ KeyExchangeAlgorithms \ diffie - hellman)
“ClientMinKeyBitLength”= dword: 00000200
显然,这与客户端https握手中缺失的值有关。
列出你的Windows HotFix:
wmic qfe list
解决方案线程:
https://communities.vmware.com/message/2604912#2604912
希望对大家有所帮助。
没有一个答案对我有用。
这是有效的方法:
而不是像这样初始化我的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...
}
事实上,我甚至不确定前两行是否有必要……
我们在Windows Server 2012R2客户端中遇到了同样的问题。
错误40表示客户端和服务器不同意使用密码套件。
在大多数情况下,服务器需要客户端无法识别的密码套件。
如果你不能修改服务器设置,解决方案是将那些“缺失”的密码套件添加到客户端:
First, go to SSLLabs SSL Labs
Enter the url of the site/api you are having problem to connect
Wait a few minutes until the test is completed
Go to 'Cipher Suites' section and read very carefully TLS 1.3 / TLS 1.2
There you will find the Cipher Suites accepted by the server
Now in your windows server, go to Regedit
Open the Key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL
There you will find 2 folders: 00010002 -->TLS 1.2 and 00010003 --> TLS 1.3
Now, edit the Functions key, and add the suites required by the server
In our case, we needed to Add TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 to 00010002 folder
我终于找到了答案(我没有注明我的来源,但它来自一次搜索);
虽然代码在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页面。