C # Ignorar erros de certificado?

159

Estou recebendo o seguinte erro durante uma solicitação de serviço da Web para um serviço da Web remoto:

Não foi possível estabelecer relação de confiança para o canal seguro SSL / TLS. ---> System.Security.Authentication.AuthenticationException: o certificado remoto é inválido de acordo com o procedimento de validação.

Existe alguma maneira de ignorar esse erro e continuar?

Parece que o certificado remoto não está assinado.

O site ao qual eu me conecto é www.czebox.cz- sinta-se à vontade para visitar o site e observe que até os navegadores lançam exceções de segurança.

JL.
fonte

Respostas:

341

Adicione um manipulador de validação de certificado. Retornar truepermitirá ignorar o erro de validação:

ServicePointManager
    .ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true;
Peter Lillevold
fonte
6
Isso é ainda mais útil do que pode parecer à primeira vista. Encontrei o problema do OP ao usar o EWS (Managed Exchanged Web Services). Eu pensei que não poderia usar essa resposta, pois não tinha acesso às chamadas SOAP de baixo nível que estavam sendo feitas por essa biblioteca gerenciada. Mas, quando olhei de novo, percebi que o ServicePointManager é autônomo. Então, adicionei o retorno de chamada acima antes de inicializar o ExchangeService e funcionou como um encanto.
Mark Meuer
2
Aqui está um exemplo de como aplicar o desvio globalmente. Para todos nós em más práticas. (Às vezes você não tem escolha) jasig.275507.n4.nabble.com/…
snowYetis
1
um grande obrigado isso resolve o problema temporariamente. Adicione este código no Startup.cs na API da Web
Sivalingaamorthy
2
O @MarkMeuer estava quase desistindo desta solução para o meu problema na API do EWS, mas depois vi o seu comentário.
Mahen 16/05
7
@MiguelVeloso, você pode recusar o curso, mas lembre-se de que nem a pergunta nem a resposta discutem o lado da segurança. O tópico é explicitamente "como ignorar o erro de validação", não "por que devemos fazer / não fazer isso", que é um tópico totalmente diferente. Entrar em uma discussão sobre por que o OP não deveria fazê-lo apenas enlameará as águas, pois os comentaristas apontaram que há casos razoáveis ​​em que você realmente faria isso. Por isso, mantemos o tópico e resolvemos o problema.
Peter Lillevold
40

Permitir todos os certificados é muito poderoso, mas também pode ser perigoso. Se você deseja permitir apenas certificados válidos mais alguns certificados, isso pode ser feito assim.

.Net core:

using (var httpClientHandler = new HttpClientHandler())
{
    httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) => {
        if (sslPolicyErrors == SslPolicyErrors.None)
        {
            return true;   //Is valid
        }

        if (cert.GetCertHashString() == "99E92D8447AEF30483B1D7527812C9B7B3A915A7")
        {
            return true;
        }
        return false;
    };
    using (var httpClient = new HttpClient(httpClientHandler))
    {
        var httpResponse = httpClient.GetAsync("https://example.com").Result;
    }
}

Estrutura .Net:

System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate (
    object sender,
    X509Certificate cert,
    X509Chain chain,
    SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
    {
        return true;   //Is valid
    }

    if (cert.GetCertHashString() == "99E92D8447AEF30483B1D7527812C9B7B3A915A7")
    {
        return true;
    }

    return false;
};

Atualizar:

Como obter cert.GetCertHashString()valor no Chrome:

Clique em Secureou Not Securena barra de endereço.

insira a descrição da imagem aqui

insira a descrição da imagem aqui

Em seguida, clique em Certificado -> Detalhes -> Impressão digital e copie o valor. Lembre-se de fazer cert.GetCertHashString().ToLower().

insira a descrição da imagem aqui

Ogglas
fonte
3
@MiguelVeloso Concordo totalmente. Isso permite ignorar a verificação (espero) de um ou dois certificados sem comprometer completamente a segurança.
Kemuel Sanchez
Como posso obter Hash Stringde um certificado?
Kiquenet
@Kiquenet Ou depurar o código e executar cert.GetCertHashString()a partir de Immediate windowou cheque cert Thumbprintno seu navegador ou MMCse estiver instalado localmente.
Ogglas
O servidor está sob nosso controle. Ainda é seguro usar o código do @ Ogglas na produção? Usando TLS / SSL, é possível parar ataques como o homem do meio?
Pingpong
Muito obrigado ajuda.
Wowo Ot
30

Método IgnoreBadCertificates:

//I use a method to ignore bad certs caused by misc errors
IgnoreBadCertificates();

// after the Ignore call i can do what ever i want...
HttpWebRequest request_data = System.Net.WebRequest.Create(urlquerystring) as HttpWebRequest;

/*
and below the Methods we are using...
*/

/// <summary>
/// Together with the AcceptAllCertifications method right
/// below this causes to bypass errors caused by SLL-Errors.
/// </summary>
public static void IgnoreBadCertificates()
{
    System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
}  

/// <summary>
/// In Short: the Method solves the Problem of broken Certificates.
/// Sometime when requesting Data and the sending Webserverconnection
/// is based on a SSL Connection, an Error is caused by Servers whoes
/// Certificate(s) have Errors. Like when the Cert is out of date
/// and much more... So at this point when calling the method,
/// this behaviour is prevented
/// </summary>
/// <param name="sender"></param>
/// <param name="certification"></param>
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns>true</returns>
private static bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    return true;
} 
Amen Ra
fonte
2
Eu tive que adicionar mais uma linha para que isso funcionasse com o meu código (estou usando o websocket4net). System.Net.ServicePointManager.CheckCertificateRevocationList = false; Logo após definir o retorno de chamada da validação de certificado do servidor.
Kalyanswaroop
24

A razão pela qual está falhando não é porque não está assinado, mas porque o certificado raiz não é confiável para o seu cliente. Em vez de desativar a validação SSL, uma abordagem alternativa seria adicionar o certificado de CA raiz à lista de CAs em que seu aplicativo confia.

Este é o certificado CA raiz no qual seu aplicativo não confia atualmente:

-----BEGIN CERTIFICATE-----
MIIFnDCCBISgAwIBAgIBZDANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJDWjEs
MCoGA1UECgwjxIxlc2vDoSBwb8WhdGEsIHMucC4gW0nEjCA0NzExNDk4M10xHjAc
BgNVBAMTFVBvc3RTaWdudW0gUm9vdCBRQ0EgMjAeFw0xMDAxMTkwODA0MzFaFw0y
NTAxMTkwODA0MzFaMFsxCzAJBgNVBAYTAkNaMSwwKgYDVQQKDCPEjGVza8OhIHBv
xaF0YSwgcy5wLiBbScSMIDQ3MTE0OTgzXTEeMBwGA1UEAxMVUG9zdFNpZ251bSBS
b290IFFDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoFz8yBxf
2gf1uN0GGXknvGHwurpp4Lw3ZPWZB6nEBDGjSGIXK0Or6Xa3ZT+tVDTeUUjT133G
7Vs51D6z/ShWy+9T7a1f6XInakewyFj8PT0EdZ4tAybNYdEUO/dShg2WvUyfZfXH
0jmmZm6qUDy0VfKQfiyWchQRi/Ax6zXaU2+X3hXBfvRMr5l6zgxYVATEyxCfOLM9
a5U6lhpyCDf2Gg6dPc5Cy6QwYGGpYER1fzLGsN9stdutkwlP13DHU1Sp6W5ywtfL
owYaV1bqOOdARbAoJ7q8LO6EBjyIVr03mFusPaMCOzcEn3zL5XafknM36Vqtdmqz
iWR+3URAUgqE0wIDAQABo4ICaTCCAmUwgaUGA1UdHwSBnTCBmjAxoC+gLYYraHR0
cDovL3d3dy5wb3N0c2lnbnVtLmN6L2NybC9wc3Jvb3RxY2EyLmNybDAyoDCgLoYs
aHR0cDovL3d3dzIucG9zdHNpZ251bS5jei9jcmwvcHNyb290cWNhMi5jcmwwMaAv
oC2GK2h0dHA6Ly9wb3N0c2lnbnVtLnR0Yy5jei9jcmwvcHNyb290cWNhMi5jcmww
gfEGA1UdIASB6TCB5jCB4wYEVR0gADCB2jCB1wYIKwYBBQUHAgIwgcoagcdUZW50
byBrdmFsaWZpa292YW55IHN5c3RlbW92eSBjZXJ0aWZpa2F0IGJ5bCB2eWRhbiBw
b2RsZSB6YWtvbmEgMjI3LzIwMDBTYi4gYSBuYXZhem55Y2ggcHJlZHBpc3UvVGhp
cyBxdWFsaWZpZWQgc3lzdGVtIGNlcnRpZmljYXRlIHdhcyBpc3N1ZWQgYWNjb3Jk
aW5nIHRvIExhdyBObyAyMjcvMjAwMENvbGwuIGFuZCByZWxhdGVkIHJlZ3VsYXRp
b25zMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQW
BBQVKYzFRWmruLPD6v5LuDHY3PDndjCBgwYDVR0jBHwweoAUFSmMxUVpq7izw+r+
S7gx2Nzw53ahX6RdMFsxCzAJBgNVBAYTAkNaMSwwKgYDVQQKDCPEjGVza8OhIHBv
xaF0YSwgcy5wLiBbScSMIDQ3MTE0OTgzXTEeMBwGA1UEAxMVUG9zdFNpZ251bSBS
b290IFFDQSAyggFkMA0GCSqGSIb3DQEBCwUAA4IBAQBeKtoLQKFqWJEgLNxPbQNN
5OTjbpOTEEkq2jFI0tUhtRx//6zwuqJCzfO/KqggUrHBca+GV/qXcNzNAlytyM71
fMv/VwgL9gBHTN/IFIw100JbciI23yFQTdF/UoEfK/m+IFfirxSRi8LRERdXHTEb
vwxMXIzZVXloWvX64UwWtf4Tvw5bAoPj0O1Z2ly4aMTAT2a+y+z184UhuZ/oGyMw
eIakmFM7M7RrNki507jiSLTzuaFMCpyWOX7ULIhzY6xKdm5iQLjTvExn2JTvVChF
Y+jUu/G0zAdLyeU4vaXdQm1A8AEiJPTd0Z9LAxL6Sq2iraLNN36+NyEK/ts3mPLL

-----END CERTIFICATE-----

Você pode decodificar e visualizar este certificado usando

este decodificador de certificado ou outro decodificador de certificado

bignum
fonte
Sim! Este é o meu caso, mas como posso adicionar o certificado no Azure, sem uma VM? Posso apenas usar a API X509Store? Vou tentar isso amanhã, mas qualquer informação é bem-vinda aqui
João Antunes
7

Para desativar a validação de certificado SSL na configuração do cliente.

<behaviors>
   <endpointBehaviors>
      <behavior name="DisableSSLCertificateValidation">
         <clientCredentials>
             <serviceCertificate>
                <sslCertificateAuthentication certificateValidationMode="None" />
              </serviceCertificate>
           </clientCredentials>
        </behavior>
d.marzo
fonte
Este é o web.config ? Alguma alternativa para o ASP.NET Core?
Shimmy Weitzhandler
5

Este código funcionou para mim. Eu tive que adicionar o TLS2 porque era nisso que o URL que eu estava interessado estava usando.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback +=
    (sender, cert, chain, sslPolicyErrors) => { return true; };
using (var client = new HttpClient())
{
    client.BaseAddress = new Uri(UserDataUrl);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new
      MediaTypeWithQualityHeaderValue("application/json"));
    Task<string> response = client.GetStringAsync(UserDataUrl);
    response.Wait();

    if (response.Exception != null)
    {
         return null;
    }

    return JsonConvert.DeserializeObject<UserData>(response.Result);
}
user2347528
fonte
3

Ignorar certificado SSL ....

        HttpClientHandler clientHandler = new HttpClientHandler();
        clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };

        // Pass the handler to httpclient(from you are calling api)
        var client = new HttpClient(clientHandler)
Rohit Jangid
fonte
2

Se você estiver usando soquetes diretamente e se autenticando como cliente, o método de retorno de chamada do Service Point Manager não funcionará. Aqui está o que funcionou para mim. POR FAVOR, USE APENAS PARA FINS DE TESTE .

var activeStream = new SslStream(networkStream, false, (a, b, c, d) => { return true; });
await activeStream.AuthenticateAsClientAsync("computer.local");

A chave aqui é fornecer o retorno de chamada da validação remota de certificado diretamente no construtor do fluxo SSL.

Mario
fonte
1

Para expandir ainda mais a postagem da BIGNUM - Idealmente, você deseja que uma solução que simule as condições que você verá na produção e modifique seu código não fará isso e poderá ser perigosa se você esquecer de retirar o código antes de implementá-lo.

Você precisará de um certificado autoassinado de algum tipo. Se você sabe o que está fazendo, pode usar o BIGNUM binário publicado, mas, se não, pode procurar o certificado. Se você estiver usando o IIS Express, já terá um desses, basta encontrá-lo. Abra o Firefox ou o navegador que você gosta e acesse o site do desenvolvedor. Você poderá visualizar as informações do certificado na barra de URLs e, dependendo do seu navegador, poderá exportar o certificado para um arquivo.

Em seguida, abra o MMC.exe e adicione o snap-in Certificado. Importe seu arquivo de certificado para o armazenamento de autoridades de certificação raiz confiáveis ​​e é tudo o que você precisa. É importante garantir que ele entre nessa loja e não em outra loja como 'Pessoal'. Se você não conhece o MMC ou os certificados, existem vários sites com informações sobre como fazer isso.

Agora, o seu computador como um todo confiará implicitamente em todos os certificados que ele próprio gerou e você não precisará adicionar código para lidar com isso especialmente. Quando você muda para a produção, ele continuará funcionando, desde que você tenha um certificado válido adequado instalado lá. Não faça isso em um servidor de produção - isso seria ruim e não funcionará para outros clientes que não sejam o próprio servidor.

Nigel Thomas
fonte
1

Isso funciona para o .Net Core. Ligue para o seu cliente Soap:

client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
                new X509ServiceCertificateAuthentication()
                {
                    CertificateValidationMode = X509CertificateValidationMode.None,
                    RevocationMode = X509RevocationMode.NoCheck
                };  
Rimi
fonte