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

时间:2017-05-09 08:22:44

标签: c# web-services ssl ssl-certificate httpwebrequest

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

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

  

[System.Net.WebException] = {"底层连接已关闭:发送时出现意外错误"}

的InnerException:

  

[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

由于我在.NET 3.5上不支持TLS 1.2,我使用了Microsoft的补丁(参见KB3154519),可以使用TLS 1.2 SecurityProtocolTypeExtensionsSslProtocolsExtensions个扩展程序。

自2017年1月(微软发布补丁程序)以来,我已经将这种方法与其他一些Web服务一起使用了,它的运行没有任何问题。

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

  

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

与我的电脑中的某些东西有关。

更新2017/05/12

我终于发现问题是与IIS相关。我的PC上的Web应用程序的应用程序池运行时标识设置为ApplicationPoolIdentity。设置为LocalSystem或我当前的用户(管理员)时,它可以正常工作。

因此,当应用程序池以ApplicationPoolIdentity运行时,我认为访问证书的内容不正确。

1 个答案:

答案 0 :(得分:1)

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

protocols

出于安全原因,某些服务器已禁用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();