web-dev-qa-db-fra.com

Impossible d'établir une relation de confiance pour le canal sécurisé SSL / TLS - SOAP

J'ai un simple appel de service Web, généré par une application Windows .NET (C #) 2.0, via le proxy de service Web généré par Visual Studio, pour un service Web également écrit en C # (2.0). Cela fonctionne depuis plusieurs années et continue de le faire dans la douzaine d’endroits où il fonctionne.

Une nouvelle installation sur un nouveau site rencontre un problème. Lorsque vous tentez d'appeler le service Web, le message suivant s'affiche:

Impossible d'établir une relation de confiance pour le canal sécurisé SSL/TLS

L'URL du service Web utilise SSL (https: //) - mais cela fonctionne depuis longtemps (et continue de le faire) à partir de nombreux autres emplacements.

Où est-ce que je regarde? Cela pourrait-il être un problème de sécurité entre Windows et .NET unique à cette installation? Si oui, où dois-je établir des relations de confiance? Je suis perdu!

309
Rob Schripsema

Pensées (basées sur la douleur du passé):

  • avez-vous un serveur DNS et une visibilité directe sur le serveur?
  • utilisez-vous le nom correct du certificat?
  • le certificat est-il toujours valide?
  • un équilibreur de charge mal configuré perturbe-t-il?
  • fait le nouveau serveur l’ordinateur ont correctement réglé l’horloge (c’est-à-dire pour que l’heure UTC soit correcte [ignorer l’heure locale, c’est en grande partie un manque de pertinence]) - c’est certainement important pour la WCF, ce qui peut donc avoir une incidence sur SOAP ordinaire?
  • existe-t-il un problème de chaîne de confiance de certificat? Si vous naviguez du serveur au service de savon, pouvez-vous obtenir le protocole SSL?
  • en rapport avec ce qui précède - le certificat a-t-il été installé au bon endroit? (vous aurez peut-être besoin d'une copie des autorités de certification racines de confiance)
  • le proxy de niveau machine du serveur est-il défini correctement? (qui diffère du proxy de l'utilisateur); voir proxycfg pour XP/2003 (pas sûr de Vista etc.)
158
Marc Gravell

Les extraits suivants résoudront le cas où le certificat SSL ne fonctionne pas correctement sur le serveur que vous appelez. Par exemple, il peut s'agir d'une signature automatique ou le nom d'hôte entre le certificat et le serveur peut ne pas correspondre.

Ceci est dangereux si vous appelez un serveur en dehors de votre contrôle direct, car vous ne pouvez plus être aussi sûr de parler au serveur auquel vous pensez être connecté. Toutefois, si vous avez affaire à des serveurs internes et que l'obtention d'un certificat "correct" n'est pas pratique, utilisez ce qui suit pour indiquer au service Web d'ignorer les problèmes de certificat et de continuer courageusement.

Les deux premiers utilisent des expressions lambda, le troisième utilise du code standard. Le premier accepte n'importe quel certificat. Les deux derniers au moins vérifient que le nom d'hôte dans le certificat est celui que vous attendez.
... espérons que vous le trouverez utile

//Trust all certificates
System.Net.ServicePointManager.ServerCertificateValidationCallback =
    ((sender, certificate, chain, sslPolicyErrors) => true);

// trust sender
System.Net.ServicePointManager.ServerCertificateValidationCallback
                = ((sender, cert, chain, errors) => cert.Subject.Contains("YourServerName"));

// validate cert by calling a function
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);

// callback used to validate the certificate in an SSL conversation
private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors)
{
    bool result = cert.Subject.Contains("YourServerName");
    return result;
}
349
Sebastian Castaldi

La solution très simple "attraper tout" est la suivante:

System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

La solution de sebastian-castaldi est un peu plus détaillée.

165
Remy

Personnellement, j'aime le plus la solution suivante:

using System.Security.Cryptography.X509Certificates;
using System.Net.Security;

... alors avant de demander l'erreur, procédez comme suit:

System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };

Trouvé ceci après consultation Solution de Luke

33
cusman

Si vous utilisez Windows 2003, vous pouvez essayer ceci:

Ouvrez la console de gestion Microsoft (Démarrer -> Exécuter -> mmc.exe);

Choisissez Fichier -> Ajouter/Supprimer un composant logiciel enfichable;

Dans l'onglet Autonome, choisissez Ajouter;

Choisissez le composant logiciel enfichable Certificats, puis cliquez sur Ajouter.

Dans l'Assistant, choisissez le compte d'ordinateur, puis choisissez Ordinateur local. Appuyez sur Terminer pour mettre fin à l'assistant.

Fermez la boîte de dialogue Ajouter/Supprimer un composant logiciel enfichable.

Accédez à Certificats (ordinateur local) et choisissez un magasin à importer:

Si vous disposez du certificat de l'autorité de certification racine pour l'entreprise qui l'a émis, choisissez Autorités de certification racines de confiance.

Si vous avez le certificat pour le serveur lui-même, choisissez Autres personnes.

Cliquez avec le bouton droit sur le magasin et choisissez Toutes les tâches -> Importer.

Suivez l'assistant et fournissez le fichier de certificat que vous avez.

Ensuite, redémarrez simplement IIS et essayez à nouveau d’appeler le service Web.

Référence: http://www.outsystems.com/NetworkForums/ViewTopic.aspx?Topic=Web-Services:-Could-not-establish-trust-relationhip-for-the-SSL/ TLS - ...

18
Diogo

Si vous ne voulez pas faire aveuglément confiance à tout le monde et créer une exception de confiance uniquement pour certains hôtes, la solution suivante est plus appropriée.

public static class Ssl
{
    private static readonly string[] TrustedHosts = new[] {
      "Host1.domain.com", 
      "Host2.domain.com"
    };

    public static void EnableTrustedHosts()
    {
      ServicePointManager.ServerCertificateValidationCallback = 
      (sender, certificate, chain, errors) =>
      {
        if (errors == SslPolicyErrors.None)
        {
          return true;
        }

        var request = sender as HttpWebRequest;
        if (request != null)
        {
          return TrustedHosts.Contains(request.RequestUri.Host);
        }

        return false;
      };
    }
}

Ensuite, appelez simplement Ssl.EnableTrustedHosts au démarrage de votre application.

16
Gregor Slavec

Microsoft outil de diagnostic SSL peut peut-être aider à identifier le problème.

UPDATE le lien a été corrigé maintenant.

7
sipwiz

Luke a écrit un très bon article à ce sujet .. assez simple .. essayez ceci

Solution de Luke

Reason (citation de son article (moins malédiction)) ".. Le problème avec le code ci-dessus est qu'il ne fonctionne pas si votre certificat n'est pas valide. Pourquoi publier sur une page Web avec un certificat SSL invalide? Parce que Je suis bon marché et je n'avais pas envie de payer Verisign ou l'un des autres ** - * s pour un certificat à ma boîte de test afin que je Quand j'ai envoyé la demande, une belle exception m'a été lancée:

System.Net.WebException La connexion sous-jacente a été fermée. Impossible d'établir une relation de confiance avec le serveur distant.

Je ne sais pas pour vous, mais pour moi, cette exception ressemblait à quelque chose qui pourrait être causé par une erreur stupide dans mon code qui faisait échouer le POST. Alors j'ai continué à chercher, à peaufiner et à faire toutes sortes de choses étranges. Ce n’est qu’après avoir cherché sur Google que j’ai découvert que le comportement par défaut après la découverte d’un certificat SSL non valide consiste à lever cette exception. .. "

6
Hans

J'ai eu un problème similaire dans l'application .NET dans Internet Explorer.

J'ai résolu le problème en ajoutant le certificat (certificat VeriSign Classe 3 dans mon cas) aux certificats d'éditeurs de confiance.

Go to Internet Options-> Content -> Publishers and import it

Vous pouvez obtenir le certificat si vous l'exportez à partir de:

Internet Options-> Content -> Certificates -> Intermediate Certification Authorities -> VeriSign Class 3 Public Primary Certification Authority - G5

merci

3
debiasej

Je viens de rencontrer ce problème. Ma résolution était de mettre à jour l'heure du système en effectuant une synchronisation manuelle sur les serveurs de temps. Pour ce faire, vous pouvez:

  • Cliquez avec le bouton droit sur l'horloge dans la barre des tâches.
  • Sélectionnez Adjust Date/Time
  • Sélectionnez l'onglet Internet Time
  • Cliquez Change Settings
  • Sélectionnez Update Now

Dans mon cas, la synchronisation était incorrecte et j'ai donc dû cliquer dessus plusieurs fois avant de la mettre à jour correctement. S'il continue de se mettre à jour de manière incorrecte, vous pouvez même essayer d'utiliser un serveur de temps différent du menu déroulant du serveur.

Essaye ça:

System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;

Notez que vous devez au moins travailler avec 4.5 .NET Framework

2
Manuel Roldan

Pour ceux qui rencontrent ce problème via un client VS une fois avec succès, une référence de service et l'exécution du premier appel ont généré cette exception: "La connexion sous-jacente a été fermée: impossible d'établir une relation de confiance pour le canal sécurisé SSL/TLS" Si vous utilisez (comme dans mon cas) une URL de point de terminaison avec l'adresse IP et que vous avez cette exception, vous devrez probablement rajouter la référence de service en procédant comme suit:

  • Ouvrez l'URL du noeud final sur Internet Explorer.
  • Cliquez sur l'erreur de certificat (icône rouge dans la barre d'adresse)
  • Cliquez sur Afficher les certificats.
  • Saisissez le nom de l'élément "nom" et remplacez l'adresse IP ou le nom que nous utilisions et obtenez l'erreur pour ce "nom".

Réessayer :). Merci

1
Ernest

J'ai eu cette erreur en cours d'exécution sur un serveur web avec url comme:

a.b.domain.com

mais il n'y avait pas de certificat pour cela, alors j'ai eu un DNS appelé

a_b.domain.com

Il suffit de mettre un indice sur cette solution car elle est arrivée en tête de classement dans Google.

1
Thomas Koelle

Dans mon cas, j'essayais de tester SSL dans mon environnement Visual Studio à l'aide de IIS 7.

Voici ce que j'ai fini par faire pour que ça fonctionne:

  • Sous mon site, dans la section "Liaisons ..." de droite dans IIS, je devais ajouter la liaison "https" au port 443 et sélectionner "Certificat de développement IIS Express".

  • Sous mon site, dans la section "Paramètres avancés ..." à droite, je devais modifier les "protocoles activés" de "http" à "https".

  • Sous l'icône "Paramètres SSL", j'ai sélectionné "Accepter" pour les certificats clients.

  • Ensuite, j'ai dû recycler le pool d'applications.

  • J'ai également dû importer le certificat d'hôte local dans mon magasin personnel à l'aide de mmc.exe.

Mon fichier web.config était déjà configuré correctement. Par conséquent, après avoir réglé tout ce qui précède, j'ai pu continuer mes tests.

0
Popo

Ma solution (VB.Net, la version "intermédiaire" (UAT) de cette application doit fonctionner avec le certificat "intermédiaire", mais sans affecter les demandes une fois qu'elles sont sur le site actif):

    ...
        Dim url As String = ConfigurationManager.AppSettings("APIURL") & "token"
        If url.ToLower().Contains("staging") Then
           System.Net.ServicePointManager.ServerCertificateValidationCallback = AddressOf AcceptAllCertifications
        End If
    ...

    Private  Function AcceptAllCertifications(ByVal sender As Object, ByVal certification As System.Security.Cryptography.X509Certificates.X509Certificate, ByVal chain As System.Security.Cryptography.X509Certificates.X509Chain, ByVal sslPolicyErrors As System.Net.Security.SslPolicyErrors) As Boolean
        Return True
    End Function
0
GreenRock