C # Игнорировать ошибки сертификата?


159

Я получаю следующую ошибку во время запроса веб-службы к удаленной веб-службе:

Не удалось установить доверительные отношения для безопасного канала SSL / TLS. ---> System.Security.Authentication.AuthenticationException: удаленный сертификат недействителен в соответствии с процедурой проверки.

Есть ли способ игнорировать эту ошибку и продолжить?

Кажется, удаленный сертификат не подписан.

Сайт, к которому я подключаюсь, www.czebox.cz- так что не стесняйтесь посещать сайт, и обратите внимание, что даже браузеры выдают исключения безопасности.

Ответы:


341

Добавьте обработчик проверки сертификата. Возврат trueпозволит игнорировать ошибку проверки:

ServicePointManager
    .ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true;

6
Это даже более полезно, чем может показаться на первый взгляд. Я столкнулся с проблемой OP при использовании управляемых обмененных веб-служб (EWS). Я думал, что не смогу использовать этот ответ, так как у меня не было доступа к низкоуровневым вызовам SOAP, которые были сделаны этой управляемой библиотекой. Но когда я взглянул на него еще раз, я понял, что ServicePointManager стоит сам по себе. Итак, я добавил вышеупомянутый обратный вызов перед инициализацией ExchangeService, и он работал как шарм.
Марк Мейер

2
Вот пример того, как применить обход в глобальном масштабе. Для всех нас в плохие практики. (Иногда у вас нет выбора) jasig.275507.n4.nabble.com/…
snowYetis

1
Большое спасибо, это временно решает проблему. Добавьте этот код в Startup.cs в Web Api
Sivalingaamorthy

2
@MarkMeuer почти собирался отказаться от этого решения для моей проблемы API EWS, но потом я увидел ваш комментарий.
Махен

7
@MiguelVeloso, вы свободны от понижения курса, но имейте в виду, что ни вопрос, ни ответ не обсуждают это с точки зрения безопасности. Тема явно «как игнорировать ошибку валидации», а не «почему мы должны делать / не делать этого», что совершенно другая тема. Зайдя в дискуссии о том, почему OP не должны делать это только мутить воду, как и комментаторы отметили, существуют разумные случаи , когда вы на самом деле было бы сделать это. Поэтому мы придерживаемся темы и решаем проблему.
Питер

40

Разрешение всех сертификатов очень эффективно, но это также может быть опасно. Если вы хотите разрешить только действительные сертификаты плюс некоторые определенные сертификаты, это можно сделать следующим образом.

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

.NET Framework:

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

Обновить:

Как получить cert.GetCertHashString()значение в Chrome:

Нажмите на Secureили Not Secureв адресной строке.

введите описание изображения здесь

введите описание изображения здесь

Затем нажмите Сертификат -> Детали -> Отпечаток и скопируйте значение. Не забудьте сделать cert.GetCertHashString().ToLower().

введите описание изображения здесь


3
@MiguelVeloso Полностью согласен. Это позволяет пропустить проверку (надеюсь) одного или двух сертификатов, не ставя под угрозу безопасность полностью.
Кемуэль Санчес

КАК я могу получить Hash Stringот сертификата?
Kiquenet

@Kiquenet Либо отлаживать код и запустить cert.GetCertHashString()из Immediate windowили проверки сертификата Thumbprintв браузере или MMCесли он установлен локально.
Огглас

Сервер находится под нашим контролем, все еще безопасно использовать код @ Ogglas на производстве? Используя TLS / SSL, можно ли остановить атаку, как «человек посередине»?
Пингпонг

Спасибо, Очень Большая Помощь.
Wowo Ot

30

Метод 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;
} 

2
Мне пришлось добавить еще одну строку, чтобы заставить это работать с моим кодом (я использую websocket4net). System.Net.ServicePointManager.CheckCertificateRevocationList = false; Сразу после настройки обратного вызова проверки сертификата сервера.
kalyanswaroop

24

Причина его сбоя не в том, что он не подписан, а в том, что ваш клиент не доверяет корневому сертификату. Вместо того чтобы отключать проверку SSL, альтернативным подходом было бы добавить сертификат корневого ЦС в список ЦС, которым доверяет ваше приложение.

Это корневой сертификат CA, которому ваше приложение в настоящее время не доверяет:

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

Вы можете расшифровать и просмотреть этот сертификат, используя

этот декодер сертификатов или другой декодер сертификатов


Да! Это мой случай, но как я могу добавить сертификат в Azure без виртуальной машины? Могу ли я просто использовать X509Store API? Я собираюсь попробовать это завтра, но любая информация приветствуется здесь
João Antunes

7

Отключить проверку SSL-сертификата в конфигурации клиента.

<behaviors>
   <endpointBehaviors>
      <behavior name="DisableSSLCertificateValidation">
         <clientCredentials>
             <serviceCertificate>
                <sslCertificateAuthentication certificateValidationMode="None" />
              </serviceCertificate>
           </clientCredentials>
        </behavior>

Это web.config ? Какие-нибудь альтернативы для ASP.NET Core?
Шимми Вайцхандлер

5

Этот код работал для меня. Мне пришлось добавить TLS2, потому что это то, что использовал интересующий меня URL.

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

3

Обойти 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)

2

Если вы используете сокеты напрямую и аутентифицируетесь как клиент, метод обратного вызова Service Point Manager не будет работать. Вот что сработало для меня. ПОЖАЛУЙСТА, ИСПОЛЬЗУЙТЕ ТОЛЬКО ДЛЯ ТЕСТИРОВАНИЯ .

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

Ключевым моментом здесь является предоставление обратного вызова для проверки удаленного сертификата прямо в конструкторе потока SSL.


1

Для дальнейшего расширения поста BIGNUM - в идеале вам нужно решение, которое будет имитировать условия, которые вы увидите в рабочей среде, и изменение кода не сделает этого и может быть опасным, если вы забудете вынуть код перед его развертыванием.

Вам понадобится какой-либо самозаверяющий сертификат. Если вы знаете, что делаете, вы можете использовать опубликованный двоичный файл BIGNUM, но если нет, вы можете отправиться на поиски сертификата. Если вы используете IIS Express, у вас уже будет один из них, вам просто нужно его найти. Откройте Firefox или любой другой браузер, который вам нравится, и перейдите на сайт разработчика. Вы должны иметь возможность просматривать информацию о сертификате в строке URL, и в зависимости от вашего браузера вы сможете экспортировать сертификат в файл.

Затем откройте MMC.exe и добавьте оснастку «Сертификат». Импортируйте файл сертификата в хранилище доверенных корневых центров сертификации, и это все, что вам нужно. Важно убедиться, что он входит в этот магазин, а не в какой-нибудь другой магазин, например «Личный». Если вы не знакомы с MMC или сертификатами, существует множество сайтов с информацией о том, как это сделать.

Теперь ваш компьютер в целом будет безоговорочно доверять любым сертификатам, которые он сам сгенерировал, и вам не нужно будет добавлять код для этой особой обработки. Когда вы перейдете к производству, он продолжит работать, если на нем установлен правильный действительный сертификат. Не делайте этого на рабочем сервере - это было бы плохо, и это не будет работать для других клиентов, кроме тех, которые находятся на самом сервере.


1

Это работает для .Net Core. Позвоните своему клиенту Soap:

client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
                new X509ServiceCertificateAuthentication()
                {
                    CertificateValidationMode = X509CertificateValidationMode.None,
                    RevocationMode = X509RevocationMode.NoCheck
                };  
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.