2017-05-09 2 views
0

Je dois implémenter une méthode qui vérifie si un service Web est disponible. Le principal problème est que l'URL est HTTPS et nécessite un certificat. J'ai donc besoin d'obtenir le certificat de la machine, puis créer un HttpWebRequest pour obtenir un HttpWebResponse.Vérifiez si le service Web HTTPS est disponible avec HttpWebRequest et le certificat SSL X509

Avec ma mise en œuvre effective, je peux récupérer le certificat, mais quand je l'appelle request.GetResponse() méthode, il jette cette exception:

[System.Net.WebException] = { "La connexion sous-jacente a été fermée: Une erreur inattendue est survenue sur un envoi "}

InnerException:

[System.IO.IOException] = {" reçu un EOF inattendu ou 0 octets de le flux de transport "}

J'ai lu beaucoup de solutions possibles mais aucune ne semble fonctionner pour moi. Je suis sur .NET 3.5.

C'est mon code

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."; 
} 

Mise à jour 2017/05/10

Depuis que je suis sur .NET 3.5 qui ne prend pas en charge TLS 1.2, je suis sur un correctif de Microsoft (voir KB3154519) qui permet d'utiliser TLS 1.2 en utilisant les classes d'extension SecurityProtocolTypeExtensions et SslProtocolsExtensions.

J'ai déjà utilisé cette méthode avec d'autres services Web depuis janvier 2017 (lorsque Microsoft a publié le correctif) et cela fonctionne sans aucun problème.

Je pense que le problème que j'ai maintenant:

[System.Net.WebException] = { "La demande a été annulée. Impossible de créer un canal sécurisé SSL/TLS de"}

a quelque chose à voir avec mon PC.

Mise à jour 2017/05/12

j'ai finalement trouvé que le problème était lié à IIS . Le pool d'applications de l'application Web sur mon PC fonctionnait avec l'identité définie sur ApplicationPoolIdentity. Lorsqu'il est défini sur LocalSystem ou sur mon utilisateur actuel (administrateur), cela a fonctionné.

Donc, je pense que quelque chose avec l'accès aux certificats n'est pas correct pendant que le pool d'applications s'exécute en tant que ApplicationPoolIdentity.

Répondre

1

scan l'URL pour voir quels fournisseurs SSL le serveur utilise.Vous pouvez le faire ici ->https://www.ssllabs.com/ssltest/analyze.html

protocols

un serveur ont le SSL3 désactivé pour des raisons de sécurité. Vous devez donc utiliser ce paramètre à la place:

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

ou d'utiliser Tls 1.2 si disponible sur le client.

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

Mise à jour Vérifiez si ce code fonctionne pour vous

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(); 
+0

Merci pour l'astuce! Super site! ;-) Il semble que seul TLS 1.2 est utilisé ([link] (https://www.ssllabs.com/ssltest/analyze.html?d=testservizi.fatturapa.it)). Mais sur mon code j'ai seulement 'SecurityProtocolType.Ssl3' et' SecurityProtocolType.Tls' et pas 'SecurityProtocolType.Tls12'. Alors qu'est-ce que je peux faire...? –

+0

Les fournisseurs SLL sont installés sur le système d'exploitation, vous devez donc vérifier quels fournisseurs sont installés sur votre système. Utilisez [IISCrypto] (https://www.nartac.com/Products/IISCrypto) pour connaître les fournisseurs que vous pouvez utiliser. Si Tls 1.2 n'est pas installé, vous devez changer le système d'exploitation. Windows Server 2008 R2 est la première fenêtre à avoir le support de tls 1.2. – migabriel

+0

Je suis sur Windows 10 dernière version. Mais j'utilise VS 2012 et .NET 3.5. –