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!
Pensées (basées sur la douleur du passé):
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;
}
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.
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
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 - ...
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.
Microsoft outil de diagnostic SSL peut peut-être aider à identifier le problème.
UPDATE le lien a été corrigé maintenant.
Luke a écrit un très bon article à ce sujet .. assez simple .. essayez ceci
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. .. "
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
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:
Adjust Date/Time
Internet Time
Change Settings
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
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:
Réessayer :). Merci
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.
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.
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