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


135

Realmente pensei que eu tinha esse problema corrigido, mas só estava disfarçado antes.

Eu tenho um serviço WCF hospedado no IIS 7 usando HTTPS. Quando eu vá para este site no Internet Explorer, ele funciona como um encanto, é porque eu ter adicionado o certificado para a loja local da autoridade de certificação raiz.

Estou desenvolvendo em uma máquina, então cliente e servidor são a mesma máquina. O certificado é autoassinado diretamente do snap-in de gerenciamento do IIS 7.

Eu recebo esse erro continuamente agora ...

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

... quando chamado do console do cliente.

Eu me dei manualmente permissões e serviço de rede ao certificado, usando findprivatekeye usando cacls.exe.

Tentei me conectar ao serviço usando SOAPUI, e isso funciona, por isso deve ser um problema no meu aplicativo cliente, que é um código baseado no que costumava funcionar com http.

Onde mais posso procurar? Parece que esgotou todas as possibilidades de por que não consigo me conectar?



Se você tem controle sobre a criação dos certificados, não se esqueça de "Nome da entidade alternativa". Como se você pudesse colocar um curinga em "* .full.domainname.com". Veja digicert.com/subject-alternative-name.htm
granadaCoder

Respostas:


198

Como solução alternativa, você pode adicionar um manipulador aos ServicePointManager's ServerCertificateValidationCallbackno lado do cliente:

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

mas lembre-se de que isso não é uma boa prática , pois ignora completamente o certificado do servidor e informa ao gerente do ponto de serviço que qualquer certificado está correto, o que pode comprometer seriamente a segurança do cliente. Você pode refinar isso e fazer uma verificação personalizada (para o nome do certificado, hash etc.). pelo menos você pode contornar problemas durante o desenvolvimento ao usar certificados de teste.


9
Acho que a maioria das configurações públicas usará um certificado adquirido, mas durante o desenvolvimento use o código acima nas instruções #if condicionais. Devs empresa deve geralmente configurar um servidor CA interna >> technet.microsoft.com/en-us/library/cc875810.aspx
Luke Puplett

2
Ajudou-me a descobrir como obter minha chamada SSL SSL WCF trabalhando com o Fiddler2 para depuração.
Roger Willcocks

2
@karank Considere colocá-lo no método Application_Start no Global.asax (consulte stackoverflow.com/a/12507094/1175419 ). Eu recomendaria fortemente o uso de uma diretiva de compilador #if DEBUG ou algo semelhante, como mencionado no comentário de Luke.
C Rich

4
Impressionante! você pode usar a expressão lambda como System.Net.ServicePointManager.ServerCertificateValidationCallback + = (se, cert, chain, sslerror) => true;
Dhanuka777

Um pouco de explicação adicional pode ser encontrada aqui: blog.effectivemessaging.com/2015_09_01_archive.html
granadaCoder

40

Quando eu tenho esse problema, é porque o client.config tinha seus pontos de extremidade como:

 https://myserver/myservice.svc 

mas o certificado estava esperando

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

Alterar os pontos de extremidade para corresponder ao FQDN do servidor resolve meu problema. Eu sei que essa não é a única causa desse problema.


Acabei de ter esse problema novamente e desta vez teve a ver com o certificado errado sendo usado. Parece que nos dois casos isso tem a ver com a correspondência correta de nomes.
Mike Cheel

3
Minha configuração gerada automaticamente teve <endpoint address = " localhost / myservice.svc " alterando isso para <endpoint address = " mymachine.mydoman.com/myservice.svc " resolvido isso.
knightscharge

Esse foi absolutamente o meu problema e levei dois dias para encontrar sua resposta. +1, eu daria +1000 se pudesse.
AussieJoe 4/03

20

os dois primeiros usam lambda, o terceiro usa código regular ... 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;
    }

1
// Confia em todos os certificados System.Net.ServicePointManager.ServerCertificateValidationCallback + = (se, cert, chain, sslerror) => {return true; }; // remetente confiável System.Net.ServicePointManager.ServerCertificateValidationCallback + = (se, cert, chain, sslerror) => {retornar cert.Subject.Contains ("ca-l-9wfvrm1.ceridian.ca"); };
VoodooChild

1
Qualquer cracker pode forjar um certificado passando em todos os testes acima. Isso é inseguro.
Bjartur Thorlacius

19

Seu problema surge porque você está usando uma chave autoassinada. O cliente não confia nessa chave nem fornece uma cadeia para validar ou uma lista de revogação de certificado.

Você tem algumas opções - você pode

  1. desative a validação de certificado no cliente (movimento ruim, ataques do tipo intermediário)

  2. use makecert para criar uma CA raiz e criar certificados a partir disso (ok, mova, mas ainda não há CRL)

  3. crie uma autoridade de certificação raiz interna usando o Windows Certificate Server ou outra solução PKI e confie nesse certificado raiz (um pouco trabalhoso de gerenciar)

  4. adquira um certificado SSL de uma das CAs confiáveis ​​(caras)


3
Em relação a (4), o StartSSL fornece um certificado de Classe 1 gratuito que funciona em todos os principais navegadores. Eles funcionam muito bem para meus meia dúzia de sites de baixa largura de banda.
Moodboom 21/05

Acho que o número 2 nesta lista ... esse URL pode ajudar: blogs.technet.microsoft.com/jhoward/2005/02/02/… "Como usar o MakeCert para obter autoridade de certificação raiz confiável e emissão de certificado SSL"
granadaCoder

1
Nota: O StartCom não é mais confiável - e acabou de ser removido do Chrome pt.wikipedia.org/wiki/StartCom
Simon_Weaver

16

Uma solução de uma linha. Adicione isso em qualquer lugar antes de chamar o servidor no lado do cliente:

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

Isso deve ser usado apenas para fins de teste porque o cliente ignorará as verificações de segurança SSL / TLS.


2
Uma solução brilhante para testes. Estamos consumindo um serviço cujo provedor tornou a segurança um inferno com uma cadeia complicada de certificados de segurança e, até que possamos obter seus certificados e encadeamentos instáveis ​​para funcionar corretamente, essa solução alternativa é a única coisa que nos permite continuar o desenvolvimento.
precisa saber é o seguinte

12

Encontrei o mesmo problema e resolvi-o com duas soluções: Primeiro, usei o snap-in "Certificados" do MMC para a "conta de computador" e arrastei o certificado autoassinado para a pasta "Autoridades de certificação raiz confiáveis" . Isso significa que o computador local (aquele que gerou o certificado) agora confiará nesse certificado. Em segundo lugar, notei que o certificado foi gerado para algum nome interno do computador, mas o serviço da web estava sendo acessado usando outro nome. Isso causou uma incompatibilidade ao validar o certificado. Geramos o certificado para computer.operations.local, mas acessamos o serviço da Web usando https://computer.internaldomain.companydomain.com . Quando trocamos o URL pelo URL usado para gerar o certificado, não tivemos mais erros.

Talvez apenas mudar URLs funcionasse, mas, ao tornar o certificado confiável, você também evita a tela vermelha no Internet Explorer, onde ele diz que não confia no certificado.


11

Se você usa o núcleo .net, tente o seguinte:

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

1
Obrigado, funciona. Mas isso não tem nada a ver com o núcleo .net. É uma receita universal :)
Alexander

7

Por favor, siga os seguintes passos:

  1. Abra o link de serviço no IE.

  2. Clique na menção de erro de certificado na barra de endereços e clique em Exibir certificados.

  3. Cheque emitido para: nome.

  4. Pegue o nome emitido e substitua a menção localhost no serviço e no nome do endereço base do terminal do cliente por Um nome de domínio totalmente qualificado (FQDN).

Por exemplo: https: // localhost : 203 / SampleService.svc Para https: // INL-126166-.groupinfra.com : 203 / SampleService.svc


Ótimo, obrigado por esta resposta! Resolvidos os problemas sem fazer alterações no código.
Vipin Dubey

6

Além das respostas acima, você poderá encontrar esse erro se o seu cliente estiver executando a versão TLS errada, por exemplo, se o servidor estiver executando apenas o TLS 1.2.

Você pode corrigi-lo usando:

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

no meu caso resposta aceita não me ajudar, mas este fez um truque
Sergey

Esta é a única resposta que corrigiu o erro no meu caso.
Tolga

5

Eu tive o mesmo problema. Eu também adicionei certificados de CA na loja local, mas fiz da maneira ERRADA.

Usando o console mmc (Iniciar -> Executar -> mmc ), você deve adicionar Certificados snap-in como conta de serviço (escolhendo a conta de serviço do IIS) ou conta de computador (que é adicionada a todas as contas da máquina)

Aqui está uma imagem do que estou falando Adicionar snap-in para uma conta de serviço ou a conta do computador

A partir daqui agora, você pode adicionar certificados de CAs ( CAs raiz confiáveis e CAs intermediárias ) e tudo funcionará bem


4

Eu tive um problema semelhante com o certificado autoassinado. Eu poderia resolvê-lo usando o nome do certificado igual ao FQDN do servidor.

Idealmente, a parte SSL deve ser gerenciada no lado do servidor. O cliente não é obrigado a instalar nenhum certificado para SSL. Além disso, algumas das postagens mencionadas sobre como ignorar o SSL do código do cliente. Mas eu discordo totalmente disso.


3

Eu apenas arrastei o certificado para a pasta "Autoridades de certificação raiz confiáveis" e pronto tudo funcionou bem.

Oh E adicionei o seguinte em um prompt de comando do administrador:

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

Não tenho certeza do nome que você precisa para o usuário (o meu é norueguês, como você pode ver!) user=NT-AUTHORITY/INTERACTIVE:?

Você pode ver todos os URLs existentes emitindo o comando: netsh http show urlacl


0

Isso ocorreu ao tentar se conectar ao serviço WCF via. o IP, por exemplo, https://111.11.111.1:port/MyService.svcenquanto estiver usando um certificado vinculado a um nome, por exemplo, mysite.com.

Mudando para o https://mysite.com:port/MyService.svcresolvido.



0

Corrigido um problema semelhante.

Percebi que tinha um pool de aplicativos em execução em uma conta que só tinha permissão de leitura do certificado usado.

O aplicativo .NET pôde recuperar corretamente o certificado, mas essa exceção foi lançada somente quando GetRequestStream () foi chamado.

As permissões de certificados podem ser gerenciadas via console do MMC


0

Se você estiver usando o núcleo .net, durante o desenvolvimento, poderá ignorar a validação de certificado usando diretivas do compilador. Dessa maneira, somente validará o certificado para liberação e não para depuração:

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

-6

Adicione isso ao seu código de cliente:

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

4
Essa resposta não é muito boa, pois não explica os riscos associados ao código.
Daved
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.