由于以下错误消息,我们无法使用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。这会改变什么吗?


当前回答

确保ServicePointManager设置是在创建HttpWebRequest之前完成的,否则它将无法工作。

工作原理:

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;

其他回答

您可以尝试安装演示证书(一些ssl提供程序提供一个月的免费演示证书),以确定问题是否与证书有效性有关。

我在仓库和档案里都有证书。我试图连接文件,得到这个错误消息。我在店里用的那台还能用。我的最佳猜测是,当我想使用文件中的证书时,由于存储了证书而导致了某种冲突。 (同一台机器上的另一个服务使用存储中的证书,而我已经使用文件中的证书开发了一个不同的服务。直到测试之前,在开发过程中都非常有效)。

对于SOAP/WCF用户,当服务器拒绝您的WS-Security配置时,也会发生此错误。客户端接收到的错误信息非常模糊,但是服务器管理员可能能够确定原因。

UsernameToken配置文件下有一个这样的例子,其中消息被<wsu:Created> time视为过期,不是有效的ISO 8601 datetime,原因可能是格式错误、不是UTC或服务器时间不匹配。

<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>

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

正如你所知道的,有很多原因可能会发生这种情况。我想我应该加上我遇到的原因…

如果你设置了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 ...