检查 HTTPS Web 服务是否可用于 HttpWebRequest 和 X509 SSL 证书



我需要实现一个检查Web服务是否可用的方法。 主要问题是URL是HTTPS并且需要证书。 所以我需要从机器上获取证书,然后创建一个HttpWebRequest来获取HttpWebResponse

通过我的实际实现,我可以检索证书,但是当我调用request.GetResponse()方法时,它会抛出此异常:

[System.Net.WebException] = {"基础连接已关闭:发送时发生意外错误"}

内部异常:

[System.IO.IOException] = {"收到意外的 EOF 或 0 字节来自 传输流"}

我阅读了许多可能的解决方案,但似乎没有一个对我有用。 我使用的是.NET 3.5

这是我的代码

using (WebClient client = new WebClient())
{
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certificates = store.Certificates.Find(X509FindType.FindByThumbprint, CertificateThumbprint, false);
if (certificates.Count == 0)
throw new Exception("No corresponding certificate found.");
X509Certificate2 certificate = certificates[0];
// Not compiling on .NET 3.5
// Error: cannot apply '+=' operator to 
//'System.Net.Security.RemoteCertificateValidationCallback' 
//and 'anonymous method'
//ServicePointManager.ServerCertificateValidationCallback +=
//    delegate(
//        object sender,
//        X509Certificate certificate,
//        X509Chain chain,
//        SslPolicyErrors sslPolicyErrors)
//    {
//        return true;
//    };
// Not compiling on .NET 3.5
// Error: cannot apply '+=' operator to 'System.Net.Security.RemoteCertificateValidationCallback' and 'lambda expression'
// ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
// Not working
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
// Not working
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(UrlWSInvioComunicazioni);
request.ClientCertificates.Add(certificate);
request.Method = "HEAD";
// throws Exception...
HttpWebResponse webResponse = request.GetResponse() as HttpWebResponse;
webResponse.Close();
response.ResultCode = ResultCode.Success;
response.ResultMessage = "Service available.";
}

更新 2017/05/10

由于我使用的是不支持 TLS 1.2 的 .NET 3.5,因此我使用的是 Microsoft 中的修补程序(请参阅KB3154519),该修补程序可以通过使用SecurityProtocolTypeExtensionsSslProtocolsExtensions扩展类来使用 TLS 1.2。

自 2017 年 1 月(Microsoft发布补丁时)以来,我已经将该方法与其他一些 Web 服务一起使用,并且它可以毫无问题地工作。

我认为我现在遇到的问题:

[System.Net.WebException] = {"请求已中止:无法创建 SSL/TLS 安全通道。

与我PC中的某些东西有关。

更新 2017/05/12

我终于发现问题与IIS有关。我的电脑上 Web 应用程序的应用程序池正在运行,"标识"设置为ApplicationPoolIdentity。当设置为LocalSystem或我的当前用户(管理员)时,它起作用了。

所以我认为当应用程序池作为应用程序池身份运行时,可以访问证书的内容是不正确的。

扫描 URL 以查看服务器正在使用哪些 SSL 提供程序。你可以在这里做到这一点 -> https://www.ssllabs.com/ssltest/analyze.html

协议

出于安全原因,某些服务器禁用了 SSL3。因此,您必须改用此设置:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls;

或使用 TLS 1.2(如果客户端上可用)。

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls12;

更新检查此代码是否适合您

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | (SecurityProtocolType)3072;
var httpRequest = (HttpWebRequest)WebRequest.Create("https://google.com");
httpRequest.Method = "GET";
httpRequest.ContentType = "text/html";
httpRequest.KeepAlive = false;
httpRequest.MaximumAutomaticRedirections = 30;
var httpResponse = (HttpWebResponse)httpRequest.GetResponse();
var responseStream = new StreamReader(httpResponse.GetResponseStream());
var strResponse = responseStream.ReadToEnd();
httpResponse.Close();
responseStream.Close();

最新更新