Não foi possível estabelecer uma relação de confiança para o canal seguro SSL / TLS – SOAP

Eu tenho uma chamada de serviço web simples, gerada por um aplicativo do windows .NET (C #) 2.0, através do proxy de serviço da web gerado pelo Visual Studio, para um serviço da web também escrito em c # (2.0). Isso funcionou por vários anos, e continua a fazê-lo em cerca de uma dúzia de lugares onde está sendo executado.

Uma nova instalação em um novo site está com problemas. Ao tentar invocar o serviço da web, ele falha com a mensagem dizendo:

Não foi possível estabelecer uma relação de confiança para o canal seguro SSL / TLS

A URL do serviço da Web usa SSL (https: //) – mas isso já vem funcionando há muito tempo (e continua sendo) de muitos outros locais.

Onde eu pareço? Este poderia ser um problema de segurança entre o Windows e o .NET exclusivo dessa instalação? Em caso afirmativo, onde eu estabeleço relações de confiança? Estou perdido!

Pensamentos (baseados em dor no passado):

  • você tem DNS e linha de visão para o servidor?
  • você está usando o nome correto do certificado?
  • o certificado ainda é válido?
  • é um balanceador de carga mal configurado balançando as coisas?
  • a nova máquina servidor tem o relógio configurado corretamente (isto é, para que a hora UTC esteja correta [ignore a hora local, é em grande parte irrelevante]) – isso certamente é importante para o WCF, portanto pode impactar o SOAP regular?
  • existe uma questão de cadeia de confiança de certificado? Se você navegar do servidor para o serviço de sabonete, poderá obter SSL?
  • relacionado ao acima – o certificado foi instalado no local correto? (você pode precisar de uma cópia nas Autoridades de Certificação Raiz Confiáveis)
  • o proxy do nível de máquina do servidor está configurado corretamente? (que diferente para o proxy do usuário); veja proxycfg para XP / 2003 (não tenho certeza sobre o Vista etc)

Os snippets a seguir corrigirão o caso em que há algo errado com o certificado SSL no servidor que você está chamando. Por exemplo, pode ser autoassinado ou o nome do host entre o certificado e o servidor pode não corresponder.

Isso é perigoso se você estiver chamando um servidor fora de seu controle direto, já que não pode mais ter certeza de que está falando com o servidor ao qual acredita estar conectado. No entanto, se você estiver lidando com servidores internos e obtendo um certificado “correto” não é prático, use o seguinte para informar o serviço da Web para ignorar os problemas de certificado e bravamente soldado em.

Os dois primeiros usam expressões lambda, o terceiro usa código regular. O primeiro aceita qualquer certificado. Os dois últimos, pelo menos, verificam se o nome do host no certificado é o esperado.
… espero que você ache útil

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

A solução muito simples “pegar tudo” é esta:

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

A solução de sebastian-castaldi é um pouco mais detalhada.

Eu pessoalmente gosto mais da seguinte solução:

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

… então antes de você solicitar o erro, faça o seguinte

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

Encontrei isto depois de consultar a solução de Luke

Se você estiver usando o Windows 2003, você pode tentar isto:

Abra o Console de Gerenciamento Microsoft (Iniciar -> Executar -> mmc.exe);

Escolha Arquivo -> Adicionar / Remover Snap-in;

Na guia Autônomo, escolha Adicionar;

Escolha o snap-in Certificados e clique em Adicionar;

No assistente, escolha a conta de computador e, em seguida, escolha computador local. Pressione Concluir para finalizar o assistente;

Feche a checkbox de diálogo Adicionar / remover snap-in;

Navegue para Certificados (Computador Local) e escolha uma loja para importar:

Se você tiver o certificado da CA raiz para a empresa que emitiu o certificado, escolha Autoridades de certificação raiz confiáveis;

Se você tiver o certificado para o próprio servidor, escolha Outras pessoas

Clique com o botão direito do mouse na loja e escolha Todas as Tarefas -> Importar

Siga o assistente e forneça o arquivo de certificado que você possui;

Depois disso, basta reiniciar o IIS e tentar chamar o serviço da web novamente.

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

Se você não quer confiar cegamente em todos e fazer uma exceção de confiança apenas para determinados hosts, a solução a seguir é mais apropriada.

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

Em seguida, basta ligar para o Ssl.EnableTrustedHosts quando o aplicativo for iniciado.

A Ferramenta de Diagnóstico SSL da Microsoft pode ajudar a identificar o problema.

UPDATE o link foi corrigido agora.

Luke escreveu um artigo muito bom sobre isso .. muito simples .. experimente

A solução de luke

Razão (citação do seu artigo (menos xingamentos)) “.. O problema com o código acima é que ele não funciona se o seu certificado não é válido. Por que eu estaria postando em uma página da web com um certificado SSL inválido? Sou barato e não queria pagar à Verisign ou a um dos outros ** – * s por um certificado na minha checkbox de teste, por isso fiz a minha assinatura. Quando enviei o pedido, recebi uma exceção adorável:

System.Net.WebException A conexão subjacente foi fechada. Não foi possível estabelecer relação de confiança com o servidor remoto.

Eu não sei sobre você, mas para mim essa exceção parecia algo que seria causado por um erro bobo no meu código que estava causando o POST a falhar. Então eu continuei procurando, fazendo ajustes e fazendo todo tipo de coisas estranhas. Somente depois que eu pesquisei no Google, descobri que o comportamento padrão depois de encontrar um certificado SSL inválido é lançar essa mesma exceção. .. ”

Acabei de encontrar este problema. Minha resolução era atualizar a hora do sistema, sincronizando manualmente com os servidores de horário. Para fazer isso, você pode:

  • Clique com o botão direito no relógio na barra de tarefas
  • Selecione Adjust Date/Time
  • Selecione a guia Internet Time da Internet Time
  • Clique em Change Settings
  • Selecione Update Now

No meu caso, isso estava sincronizando incorretamente, então tive que clicar várias vezes antes de atualizá-lo corretamente. Se continuar a atualizar incorretamente, você pode até tentar usar um servidor de horário diferente na lista suspensa do servidor.

Eu tive um problema semelhante no aplicativo .NET no Internet Explorer.

Eu resolvi o problema de adicionar o certificado (certificado VeriSign Classe 3 no meu caso) aos certificados de editores confiáveis.

Vá para Opções da Internet-> Conteúdo -> Editores e importe-o

Você pode obter o certificado se exportá-lo de:

Opções da Internet-> Conteúdo -> Certificados -> Autoridades de Certificação Intermediárias -> Autoridade de Certificação Primária Pública da VeriSign Classe 3 – G5

Eu tive este erro correndo contra um servidor web com URL como:

 abdomain.com 

mas não havia certificado para isso, então eu tenho um DNS chamado

 a_b.domain.com 

Apenas colocando a dica para esta solução aqui desde que isso surgiu no topo do google.

Para aqueles que estão tendo esse problema por meio de um cliente VS, uma vez adicionada com êxito uma referência de serviço e tentando executar a primeira chamada obteve esta exceção: “A conexão subjacente foi fechada: não foi possível estabelecer relação de confiança para o canal seguro SSL / TLS” você está usando (como no meu caso) uma URL de endpoint com o endereço IP e recebeu essa exceção, então você provavelmente precisará adicionar novamente a referência de serviço executando estas etapas:

  • Abra o URL do ponto de extremidade no Internet Explorer.
  • Clique no erro do certificado (ícone vermelho na barra de endereços)
  • Clique em Exibir certificados.
  • Pegue o emitido para: “nome” e substitua o endereço IP ou o nome que estávamos usando e obtendo o erro para este “nome”.

Tente novamente :). obrigado

No meu caso, eu estava tentando testar o SSL no meu ambiente do Visual Studio usando o IIS 7.

Foi o que acabei fazendo para que funcionasse:

  • Sob o meu site na seção ‘Ligações …’ à direita no IIS, tive que adicionar a binding ‘https’ à porta 443 e selecione “Certificado de Desenvolvimento do IIS Express”.

  • Em meu site na seção “Configurações avançadas …” à direita, tive que alterar os “Protocolos habilitados” de “http” para “https”.

  • No ícone ‘Configurações SSL’, selecionei ‘Aceitar’ para certificados de clientes.

  • Então eu tive que reciclar o pool de aplicativos.

  • Eu também tive que importar o certificado de host local para o meu armazenamento pessoal usando mmc.exe.

Meu arquivo web.config já estava configurado corretamente, então depois que eu terminei todos os itens acima, eu pude continuar meus testes.

Tente isto:

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

Observe que você tem que trabalhar pelo menos com 4.5 framework .NET

Se não funcionar um sertificate incorreto, quando ServerCertificateValidationCallback retornar true; Meu código ServerCertificateValidationCallback:

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

Meu código que o impedido executa o ServerCertificateValidationCallback:

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

Função 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); } 

Desativei o código CertificateValidation e o ServerCertificateValidationCallback está funcionando muito bem