c# httpclient - Impossibile stabilire una relazione di trust per il canale protetto SSL / TLS:SOAP




ignore errors (13)

Ho una semplice chiamata al servizio web, generata da un'applicazione Windows .NET (C #) 2.0, tramite il proxy del servizio Web generato da Visual Studio, per un servizio Web scritto anche in C # (2.0). Questo ha funzionato per diversi anni, e continua a farlo nella decina di luoghi in cui è in esecuzione.

Una nuova installazione in un nuovo sito è in esecuzione in un problema. Quando si tenta di richiamare il servizio Web, fallisce con il messaggio che dice:

Impossibile stabilire una relazione di trust per il canale protetto SSL / TLS

L'URL del servizio web utilizza SSL (https: //), ma questo ha funzionato da molto tempo (e continua a farlo) da molte altre posizioni.

Dove guardo? Questo potrebbe essere un problema di sicurezza tra Windows e .NET che è unico per questa installazione? In tal caso, dove imposto le relazioni di fiducia? Mi sono perso!


Answers

Ho avuto un problema simile nell'app .NET in Internet Explorer.

Ho risolto il problema aggiungendo il certificato (certificato VeriSign Classe 3 nel mio caso) ai certificati degli editori attendibili.

Vai a Opzioni Internet-> Contenuto -> Editori e importa

Puoi ottenere il certificato se lo esporti da:

Opzioni Internet-> Contenuto -> Certificati -> Autorità di certificazione intermedie -> Autorità di certificazione primaria pubblica di Classe 3 VeriSign - G5


Ho appena incontrato questo problema. La mia risoluzione è stata quella di aggiornare l'ora del sistema sincronizzando manualmente i time server. Per fare questo puoi:

  • Fare clic con il tasto destro del mouse sulla barra delle applicazioni
  • Seleziona Adjust Date/Time
  • Seleziona la scheda Internet Time
  • Fai clic su Change Settings
  • Seleziona Update Now

Nel mio caso la sincronizzazione non era corretta, quindi ho dovuto fare clic più volte prima che si aggiornasse correttamente. Se continua a essere aggiornato in modo errato, puoi persino provare a utilizzare un server orario differente dal menu a discesa del server.


I seguenti frammenti risolveranno il caso in cui c'è qualcosa di sbagliato nel certificato SSL sul server che stai chiamando. Ad esempio, potrebbe essere autofirmato o il nome host tra il certificato e il server potrebbe non corrispondere.

Questo è pericoloso se stai chiamando un server al di fuori del tuo controllo diretto, dal momento che non puoi più essere sicuro che stai parlando al server che pensi di essere connesso. Tuttavia, se si ha a che fare con server interni e ottenere un certificato "corretto" non è pratico, utilizzare quanto segue per comunicare al servizio Web di ignorare i problemi del certificato e di attaccare coraggiosamente il soldato.

Le prime due usano espressioni lambda, la terza usa codice normale. Il primo accetta qualsiasi certificato. Gli ultimi due controllano almeno che il nome host nel certificato sia quello che ci si aspetta.
... spero che tu 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;
}

Se stai usando Windows 2003, puoi provare questo:

Apri Microsoft Management Console (Start -> Esegui -> mmc.exe);

Scegli File -> Aggiungi / Rimuovi snap-in;

Nella scheda Standalone, selezionare Aggiungi;

Scegli lo snap-in Certificati e fai clic su Aggiungi;

Nella procedura guidata, selezionare l'account del computer, quindi scegliere Computer locale. Premere Fine per terminare la procedura guidata;

Chiudi la finestra di dialogo Aggiungi / Rimuovi snap-in;

Passare a Certificati (computer locale) e scegliere un negozio da importare:

Se si dispone del certificato CA radice per la società che ha emesso il certificato, selezionare Autorità di certificazione radice attendibili;

Se si dispone del certificato per il server stesso, selezionare Altre persone

Fai clic con il tasto destro del mouse sul negozio e seleziona Tutte le attività -> Importa

Segui la procedura guidata e fornisci il file del certificato che hai;

Dopodiché, riavvia semplicemente IIS e prova a chiamare di nuovo il servizio web.

Riferimento: http://www.outsystems.com/NetworkForums/ViewTopic.aspx?Topic=Web-Services:-Could-not-establish-trust-relationship-for-the-SSL/TLS- ...


Se non funziona funziona male, quando ServerCertificateValidationCallback restituisce true; My ServerCertificateValidationCallback code:

ServicePointManager.ServerCertificateValidationCallback += delegate
{
    LogWriter.LogInfo("Проверка сертификата отключена, на уровне ServerCertificateValidationCallback");
    return true;
};

Il mio codice che impedisce l'esecuzione di ServerCertificateValidationCallback:

     if (!(ServicePointManager.CertificatePolicy is CertificateValidation))
    {
        CertificateValidation certValidate = new CertificateValidation();
        certValidate.ValidatingError += new CertificateValidation.ValidateCertificateEventHandler(this.OnValidateCertificateError);
        ServicePointManager.CertificatePolicy = certValidate;
    }

Funzione OnValidateCertificateError:

private void OnValidateCertificateError(object sender, CertificateValidationEventArgs e)
{
    string msg = string.Format(Strings.OnValidateCertificateError, e.Request.RequestUri, e.Certificate.GetName(), e.Problem, new Win32Exception(e.Problem).Message);
    LogWriter.LogError(msg);
    //Message.ShowError(msg);
}

Ho disabilitato il codice CertificateValidation e ServerCertificateValidationCallback in esecuzione molto bene


Ho avuto questo errore in esecuzione contro un server web con url come:

a.b.domain.com

ma non c'era un certificato per questo, quindi ho chiamato un DNS

a_b.domain.com

Mettendo solo un accenno a questa soluzione qui da quando è arrivato in cima a google.


Luca ha scritto un bel articolo su questo ... piuttosto semplice ... provalo

La soluzione di Luke

Motivo (citazione dal suo articolo (meno cursing)) ".. Il problema con il codice sopra riportato è che non funziona se il tuo certificato non è valido. Perché dovrei postare su una pagina web con certificato SSL non valido? Perché Sono a buon mercato e non avevo voglia di pagare Verisign o uno degli altri ** - * s per un certificato alla mia casella di prova, quindi mi sono autofirmato. Quando ho inviato la richiesta ho ricevuto un'eccezionale eccezione a me:

System.Net.WebException La connessione sottostante è stata chiusa. Impossibile stabilire una relazione di trust con il server remoto.

Non so voi, ma per me quell'eccezione sembrava qualcosa che sarebbe stato causato da uno stupido errore nel mio codice che stava causando il fallimento del POST. Così ho continuato a cercare, a modificare e fare ogni genere di cose strane. Solo dopo aver cercato su google cosa ho scoperto che il comportamento predefinito dopo aver incontrato un certificato SSL non valido è di lanciare questa eccezione. .."


La semplice soluzione "catch all" è questa:

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

La soluzione di sebastian-castaldi è un po 'più dettagliata.


Personalmente mi piace di più la seguente soluzione:

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

... quindi prima di richiedere l'errore, procedi come segue

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

Trovato questo dopo aver consultato la soluzione di Luke



Se non vuoi fidarti ciecamente di tutti e fare un'eccezione di fiducia solo per alcuni host, la seguente soluzione è più appropriata.

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

Quindi chiama semplicemente Ssl.EnableTrustedHosts all'avvio dell'app.


Nel mio caso stavo provando a testare SSL nel mio ambiente Visual Studio usando IIS 7.

Questo è quello che ho finito per farlo funzionare:

  • Sotto il mio sito nella sezione "Bindings ..." a destra in IIS, ho dovuto aggiungere il binding "https" alla porta 443 e selezionare "IIS Express Developmentement Certificate".

  • Sotto il mio sito nella sezione "Impostazioni avanzate ..." sulla destra ho dovuto modificare i "Protocolli abilitati" da "http" a "https".

  • Sotto l'icona 'Impostazioni SSL' ho selezionato 'Accetta' per i certificati client.

  • Quindi ho dovuto riciclare il pool di app.

  • Ho anche dovuto importare il certificato host locale nel mio negozio personale usando mmc.exe.

Il mio file web.config era già configurato correttamente, quindi dopo aver risolto tutti i problemi sopra elencati, sono stato in grado di continuare i miei test.


Per espandere ulteriormente il post di BIGNUM - Idealmente vuoi una soluzione che simuli le condizioni che vedrai in produzione e modificare il tuo codice non lo farà e potrebbe essere pericoloso se ti dimentichi di togliere il codice prima di distribuirlo.

Avrai bisogno di un certificato autofirmato di qualche tipo. Se sai cosa stai facendo, puoi usare il binario BIGNUM pubblicato, ma se no puoi andare a cercare il certificato. Se stai usando IIS Express ne avrai già uno, dovrai solo trovarlo. Apri Firefox o il browser che ti piace e vai al tuo sito web di sviluppo. Dovresti essere in grado di visualizzare le informazioni del certificato dalla barra degli indirizzi e, in base al tuo browser, dovresti essere in grado di esportare il certificato in un file.

Quindi, aprire MMC.exe e aggiungere lo snap-in Certificato. Importa il file del certificato nell'archivio Autorità di certificazione dei certificati attendibili e tutto ciò di cui hai bisogno. È importante assicurarsi che entri in quel negozio e non in un altro negozio come "Personale". Se non hai familiarità con MMC o certificati, ci sono numerosi siti Web con informazioni su come farlo.

Ora, il tuo computer nel suo complesso si fiderà implicitamente di tutti i certificati che ha generato da solo e non avrai bisogno di aggiungere codice per gestirlo in modo speciale. Quando passi alla produzione, continuerà a funzionare se hai installato un certificato valido appropriato. Non farlo su un server di produzione: sarebbe male e non funzionerà con altri client diversi da quelli sul server stesso.







c# .net ssl trust