Come risolvere "Impossibile stabilire una relazione di fiducia per il canale sicuro SSL / TLS con autorità"


135

Pensavo davvero di aver risolto questo problema, ma era solo mascherato prima.

Ho un servizio WCF ospitato in IIS 7 usando HTTPS. Quando passo in rassegna a questo sito in Internet Explorer, funziona come un fascino, questo è perché io ho aggiunto il certificato all'archivio locale di un'autorità di certificazione.

Sto sviluppando su 1 macchina, quindi client e server sono la stessa macchina. Il certificato è autofirmato direttamente dallo snap-in di gestione di IIS 7.

Ricevo continuamente questo errore ora ...

Impossibile stabilire una relazione di fiducia per il canale sicuro SSL / TLS con l'autorità.

... quando viene chiamato dalla console client.

Mi sono dato manualmente le autorizzazioni e il servizio di rete al certificato, usando findprivatekeye usando cacls.exe.

Ho provato a connettermi al servizio tramite SOAPUI e funziona, quindi deve essere un problema nella mia applicazione client, che è un codice basato su ciò che funzionava con http.

Dove altro posso guardare sembra che abbia esaurito tutte le possibilità sul perché non riesco a connettermi?



Se hai il controllo della creazione dei certificati, non dimenticare "Nome soggetto alternativo". Come se potessi mettere un jolly in "* .full.domainname.com". Visita digicert.com/subject-alternative-name.htm
granadaCoder

Risposte:


198

Come una soluzione si potrebbe aggiungere un gestore per le ServicePointManager's ServerCertificateValidationCallbacksul lato client:

System.Net.ServicePointManager.ServerCertificateValidationCallback +=
    (se, cert, chain, sslerror) =>
        {
            return true;
        };

ma tieni presente che questa non è una buona pratica in quanto ignora completamente il certificato del server e dice al gestore del punto di servizio che qualunque certificato va bene può compromettere seriamente la sicurezza del client. È possibile perfezionarlo ed eseguire alcuni controlli personalizzati (per nome certificato, hash ecc.). almeno è possibile aggirare i problemi durante lo sviluppo quando si utilizzano i certificati di prova.


9
Penso che la maggior parte delle installazioni pubbliche utilizzerà un certificato acquistato, ma durante lo sviluppo utilizzare il codice sopra nelle istruzioni condizionali #if. Gli sviluppatori aziendali dovrebbero generalmente installare un server CA interno >> technet.microsoft.com/en-us/library/cc875810.aspx
Luke Puplett,

2
Mi ha aiutato a capire come far funzionare la mia chiamata WCF SSL con Fiddler2 per il debug.
Roger Willcocks

2
@karank Considerare di inserirlo nel metodo Application_Start in Global.asax (consultare stackoverflow.com/a/12507094/1175419 ). Consiglio vivamente di usare una direttiva del compilatore #if DEBUG o qualcosa di simile come menzionato nel commento di Luke.
Rich C

4
Eccezionale! puoi usare l'espressione lambda come System.Net.ServicePointManager.ServerCertificateValidationCallback + = (se, cert, chain, sslerror) => true;
Dhanuka777,

Una piccola spiegazione in più può essere trovata qui: blog.effectivemessaging.com/2015_09_01_archive.html
granadaCoder

40

Quando ho questo problema è perché client.config aveva i suoi endpoint come:

 https://myserver/myservice.svc 

ma il certificato era in attesa

 https://myserver.mydomain.com/myservice.svc

La modifica degli endpoint in modo che corrisponda al nome di dominio completo del server risolve il mio problema. So che questa non è l'unica causa di questo problema.


Ho appena avuto di nuovo questo problema e questa volta è stato necessario utilizzare il certificato errato. Sembra che in entrambi i casi abbia a che fare con la corrispondenza corretta dei nomi.
Mike Cheel,

3
La mia configurazione generata automaticamente aveva <endpoint address = " localhost / myservice.svc " cambiando questo in <endpoint address = " mymachine.mydoman.com/myservice.svc " risolto questo problema.
Carica cavalieri

Questo è stato assolutamente il mio problema e mi ci sono voluti due giorni per trovare la tua risposta. +1, ti darei +1000 se potessi.
AussieJoe

20

i primi due usano lambda, il terzo usa un codice normale ... spero che lo trovi 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 = false;
        if (cert.Subject.ToUpper().Contains("YourServerName"))
        {
            result = true;
        }

        return result;
    }

1
// Confida in tutti i certificati System.Net.ServicePointManager.ServerCertificateValidationCallback + = (se, cert, chain, sslerror) => {return true; }; // mittente attendibile System.Net.ServicePointManager.ServerCertificateValidationCallback + = (se, cert, chain, sslerror) => {return cert.Subject.Contains ("ca-l-9wfvrm1.ceridian.ca"); };
VoodooChild

1
Qualsiasi cracker potrebbe falsificare un certificato superando tutti i test sopra indicati. Questo non è sicuro.
Bjartur Thorlacius,

19

Il tuo problema sorge perché stai usando una chiave autofirmata. Il client non considera attendibile questa chiave, né la chiave stessa fornisce una catena per la convalida o un elenco di revoche di certificati.

Hai alcune opzioni - puoi

  1. disattivare la convalida del certificato sul client (mossa sbagliata, gli attacchi man in the middle abbondano)

  2. usa makecert per creare una CA root e creare certificati da quella (ok sposta, ma non c'è ancora CRL)

  3. creare una CA radice interna utilizzando Windows Certificate Server o altra soluzione PKI, quindi fidarsi di quel certificato root (un po 'una seccatura da gestire)

  4. acquistare un certificato SSL da una delle autorità di certificazione attendibili (costoso)


3
Per quanto riguarda (4), StartSSL ti darà effettivamente un certificato gratuito di Classe 1 che funziona in tutti i principali browser. Funzionano perfettamente per me per i miei mezza dozzina di siti con larghezza di banda ridotta.
moodboom

Penso che # 2 in questo elenco ... questo URL potrebbe aiutare: blogs.technet.microsoft.com/jhoward/2005/02/02/… "Come usare MakeCert per l'autorità di certificazione radice attendibile e l'emissione del certificato SSL"
granadaCoder

1
Nota: StartCom non è più affidabile - ed è appena stato rimosso da Chrome en.wikipedia.org/wiki/StartCom
Simon_Weaver

16

Una soluzione a una linea. Aggiungi questo ovunque prima di chiamare il server sul lato client:

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

Questo dovrebbe essere usato solo a scopo di test perché il client salterà i controlli di sicurezza SSL / TLS.


2
Una soluzione brillante per i test. Stiamo consumando un servizio il cui fornitore ha reso la sicurezza un inferno vivente con una catena contorta di certificati di sicurezza e fino a quando non riusciremo a far funzionare correttamente i loro certificati e il concatenamento traballanti, questa soluzione è l'unica cosa che ci consente di continuare lo sviluppo.
markaaronky,

12

Ho riscontrato lo stesso problema e sono stato in grado di risolverlo con due soluzioni: in primo luogo, ho utilizzato lo snap-in MMC "Certificati" per "Account computer" e trascinato il certificato autofirmato nella cartella "Autorità di certificazione radice attendibili" . Ciò significa che il computer locale (quello che ha generato il certificato) ora si fiderà di quel certificato. In secondo luogo, ho notato che il certificato è stato generato per un nome di computer interno, ma al servizio Web si accedeva utilizzando un altro nome. Ciò ha causato una mancata corrispondenza durante la convalida del certificato. Abbiamo generato il certificato per computer.operations.local, ma abbiamo effettuato l'accesso al servizio Web utilizzando https://computer.internaldomain.companydomain.com . Quando abbiamo passato l'URL a quello utilizzato per generare il certificato non abbiamo più riscontrato errori.

Forse il semplice cambio di URL avrebbe funzionato, ma rendendo affidabile il certificato eviti anche la schermata rossa in Internet Explorer dove ti dice che non si fida del certificato.


11

Se usi .net core prova questo:

client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
        new X509ServiceCertificateAuthentication()
        {
            CertificateValidationMode = X509CertificateValidationMode.None,
            RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck
        };

1
Grazie, funziona Ma non ha nulla a che fare con il core .net. È una ricetta universale :)
Alexander

7

Si prega di fare i seguenti passi:

  1. Apri il collegamento al servizio in IE.

  2. Fare clic sulla menzione dell'errore del certificato nella barra degli indirizzi e fare clic su Visualizza certificati.

  3. Assegno rilasciato a: nome.

  4. Prendere il nome emesso e sostituire la menzione localhost nel nome dell'indirizzo di base dell'endpoint del servizio e del client con un nome di dominio completo (FQDN).

Ad esempio: https: // localhost : 203 / SampleService.svc A https: // INL-126166-.groupinfra.com : 203 / SampleService.svc


Ottimo, grazie per questa risposta! Risolti i problemi senza apportare modifiche al codice.
Vipin Dubey,

6

Oltre alle risposte sopra, potresti riscontrare questo errore se il tuo client esegue una versione TLS errata, ad esempio se il server esegue solo TLS 1.2.

Puoi risolverlo usando:

// tested in .NET 4.5:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

nel mio caso la risposta accettata non mi ha aiutato, ma questo ha fatto un trucco
Sergey

Questa è l'unica risposta che ha corretto l'errore nel mio caso.
Tolga,

5

Ho avuto lo stesso problema. Avevo anche aggiunto certificati CA nell'archivio locale, ma ho sbagliato.

Utilizzando mmc Console (Start -> Esegui -> mmc ) è necessario aggiungere lo snap-in Certificati come account di servizio (scegliendo l'account di servizio di IIS) o account di computer (si aggiunge per ogni account sulla macchina)

Ecco un'immagine di ciò di cui sto parlando Aggiungi snap-in per un account di servizio o per l'account del computer

Da qui ora è possibile aggiungere certificati di CA ( CA principali attendibili e CA intermedie ) e tutto funzionerà correttamente


4

Ho avuto un problema simile con il certificato autofirmato. Potrei risolverlo usando il nome del certificato stesso del nome FQDN del server.

Idealmente, la parte SSL dovrebbe essere gestita sul lato server. Il client non è tenuto ad installare alcun certificato per SSL. Inoltre, alcuni dei post menzionati sull'esclusione di SSL dal codice client. Ma non sono assolutamente d'accordo.


3

Ho appena trascinato il certificato nella cartella "Autorità di certificazione radice attendibili" e voilà tutto ha funzionato bene.

Oh. E ho prima aggiunto quanto segue da un prompt dei comandi dell'amministratore:

netsh http add urlacl url=https://+:8732/Servicename user=NT-MYNDIGHET\INTERAKTIV

Non sono sicuro del nome che ti serve per l'utente (il mio è norvegese come puoi vedere!) user=NT-AUTHORITY/INTERACTIVE:?

Puoi vedere tutti gli urlacl esistenti emettendo il comando: netsh http show urlacl


0

Ciò si è verificato durante il tentativo di connessione al servizio WCF tramite. l'IP, ad esempio https://111.11.111.1:port/MyService.svcdurante l'utilizzo di un certificato associato a un nome, ad esempio mysite.com.

Passando al https://mysite.com:port/MyService.svcrisolto.



0

Ho appena risolto un problema simile.

Mi sono reso conto di disporre di un pool di applicazioni in esecuzione con un account che aveva solo l'autorizzazione di lettura sul certificato utilizzato.

L'applicazione .NET è stata in grado di recuperare correttamente il certificato ma quell'eccezione è stata generata solo quando è stato chiamato GetRequestStream ().

Le autorizzazioni per i certificati possono essere gestite tramite la console MMC


0

Se si utilizza .net core, durante lo sviluppo è possibile ignorare la convalida del certificato utilizzando le direttive del compilatore. In questo modo convaliderà solo il certificato per il rilascio e non per il debug:

#if (DEBUG)
        client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
                new X509ServiceCertificateAuthentication()
                {
                    CertificateValidationMode = X509CertificateValidationMode.None,
                    RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck
                };   #endif

-6

Aggiungi questo al tuo codice cliente:

ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(
    delegate
    {
        return true;
    });

4
Questa risposta non è molto buona, in quanto non spiega i rischi associati al codice.
DaveD,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.