Як вирішити "Не вдалося встановити довірчі відносини для безпечного каналу SSL / TLS з владою"


135

Дійсно думав, що я вирішив цю проблему, але це було замасковано лише раніше.

У мене служба WCF розміщена в IIS 7 за допомогою HTTPS. Коли я переглядаю цей сайт в Internet Explorer, він працює як шарм, це тому , що я б додав сертифікат на локальне кореневе сховище сертифікатів повноважень.

Я розвиваюсь на 1 машині, тож клієнт і сервер - одна і та ж машина. Сертифікат підписується самостійно безпосередньо з оснащення управління IIS 7.

Я постійно отримую цю помилку зараз ...

Не вдалося встановити довірчі відносини для захищеного каналу SSL / TLS з повноваженнями.

... при виклику з консолі клієнта.

Я вручну надавав собі дозволи та сервісне обслуговування сертифіката, використовуючи findprivatekeyта використовуючи cacls.exe.

Я спробував підключитися до сервісу за допомогою SOAPUI, і це працює, тому це повинно бути проблемою в моїй клієнтській програмі, що є кодом на основі того, що раніше працювало з http.

Де ще я можу подивитися, я, здається, вичерпав усі можливості щодо того, чому я не можу підключитися?



Якщо у вас є контроль над створенням сертифікатів, не забувайте про "Альтернативне ім'я теми". Можливо, ви можете поставити підстановку на "* .full.domainname.com". Дивіться digicert.com/subject-alternative-name.htm
granadaCoder

Відповіді:


198

В якості тимчасового рішення можна додати обробник до ServicePointManager«з ServerCertificateValidationCallbackна стороні клієнта:

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

але майте на увазі, що це не є хорошою практикою, оскільки він повністю ігнорує серверний сертифікат і повідомляє менеджеру сервісного центру, що будь-який сертифікат є нормальним, це може серйозно пошкодити безпеку клієнта. Ви можете уточнити це та виконати спеціальну перевірку (на ім'я сертифіката, хеш тощо). принаймні, ви можете обійти проблеми під час розробки при використанні тестових сертифікатів.


9
Я думаю, що більшість загальнодоступних налаштувань використовуватимуть придбаний сертифікат, але під час розробника використовувати вищезазначений код у умовних операторах #if Як правило, Enterprise Devs має налаштувати внутрішній сервер CA >> technet.microsoft.com/en-us/library/cc875810.aspx
Люк Пуплетт

2
Допоміг мені зрозуміти, як змусити SSL WCF працювати з Fiddler2 для налагодження.
Роджер Віллокс

2
@karank Подумайте про те, як застосувати метод Application_Start у Global.asax (див. stackoverflow.com/a/12507094/1175419 ). Я настійно рекомендую використовувати директиву компілятора #if DEBUG або щось подібне, як згадується в коментарі Лука.
Річ С

4
Дивовижно! ви можете використовувати лямбда-вираз як System.Net.ServicePointManager.ServerCertificateValidationCallback + = (se, cert, ланцюг, sslerror) => true;
Dhanuka777

Трохи додаткового пояснення можна знайти тут: blog.effectivemessaging.com/2015_09_01_archive.html
granadaCoder

40

Коли у мене є ця проблема, це тому, що client.config мав свої кінцеві точки, як:

 https://myserver/myservice.svc 

але сертифікат очікував

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

Зміна кінцевих точок на відповідність FQDN сервера вирішує мою проблему. Я знаю, що це не єдина причина цієї проблеми.


У мене просто з’явилася ця проблема ще раз, і цього разу це було пов’язано з неправильним сертифікатом. Схоже, що в обох випадках це пов'язано з відповідним узгодженням імен.
Майк Чіл

3
Моя автоматично створена конфігурація мала <endpoint address = " localhost / myservice.svc ", змінивши це на <endpoint address = " mymachine.mydoman.com/myservice.svc ", це вирішило.
лицарський збір

Це було абсолютно моїм питанням, і мені знадобилося два дні, щоб знайти вашу відповідь. +1, я б тобі дав +1000, якби міг.
AussieJoe

20

перші два використовують лямбда, треті використовують звичайний код ... сподіваюся, ви вважаєте це корисним

            //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
// Довіряйте всім сертифікатам System.Net.ServicePointManager.ServerCertificateValidationCallback + = (se, cert, ланцюг, sslerror) => {return true; }; // довірити відправника System.Net.ServicePointManager.ServerCertificateValidationCallback + = (se, cert, ланцюг, sslerror) => {return cert.Subject.Contains ("ca-l-9wfvrm1.ceridian.ca"); };
VoodooChild

1
Будь-який зломщик може підробити сертифікат, який проходить всі вищеперелічені тести. Це незахищено.
Bjartur Thorlacius

19

Ваша проблема виникає через те, що ви використовуєте ключ, що підписується самостійно. Клієнт не довіряє цьому ключу, а також сам ключ не забезпечує ланцюжок для перевірки чи списку відкликання сертифіката.

У вас є кілька варіантів - ви можете

  1. вимкнути перевірку сертифікату на клієнта (поганий хід, людина в середині атакує багато)

  2. використовуйте makecert для створення кореневого ЦС та створення сертифікатів із цього (нормально рухатись, але досі немає CRL)

  3. створіть внутрішній кореневий центр сервісу за допомогою сервера сертифікатів Windows або іншого рішення PKI, після чого довіряйте цьому кореневому серту (трохи болю для управління)

  4. придбати сертифікат SSL у одного із надійних ЦА (дорого)


3
Щодо (4), StartSSL фактично надасть вам безкоштовний сертифікат класу 1, який працює у всіх основних браузерах. Вони чудово працюють для мене на півтора десятка сайтів із низькою пропускною здатністю.
moodboom

Я думаю, що №2 у цьому списку ... ця URL-адреса може допомогти: blogs.technet.microsoft.com/jhoward/2005/02/02/… "Як використовувати MakeCert для надійного кореневого сертифікаційного органу та видачі сертифікатів SSL"
granadaCoder

1
Примітка: StartCom більше не заслуговує на довіру - і його щойно видалили з Chrome en.wikipedia.org/wiki/StartCom
Simon_Weaver

16

Рішення на одну лінію Додайте це будь-де, перш ніж викликати сервер на стороні клієнта:

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

Це слід використовувати лише для тестування, оскільки клієнт буде пропускати перевірки безпеки SSL / TLS.


2
Блискуче рішення для тестування. Ми споживаємо послугу, постачальник якої перетворив безпеку на життя пекло за допомогою складних ланцюжків сертифікатів безпеки, і поки ми не зможемо отримати їхні непрості сертифікати та ланцюжок для належної роботи, це вирішення - це єдине, що дозволяє нам продовжувати розвиток.
markaaronky

12

Я зіткнувся з тією ж проблемою, і мені вдалося вирішити її двома рішеннями: по-перше, я застосував оснащення MMC "Сертифікати" для "Облікового запису комп'ютера" і перетягнув самопідписаний сертифікат у папку "Довірені кореневі органи сертифікації" . Це означає, що локальний комп'ютер (той, який генерував сертифікат) тепер буде довіряти цьому сертифікату. По-друге, я помітив, що сертифікат генерується для якогось внутрішнього імені комп'ютера, але доступ до веб-сервісу здійснюється за допомогою іншого імені. Це спричинило невідповідність під час перевірки сертифіката. Ми створили сертифікат для computer.operations.local, але отримали доступ до веб-служби за допомогою https://computer.internaldomain.companydomain.com . Коли ми переключили URL на той, який використовується для створення сертифіката, у нас більше помилок не було.

Можливо, просто переключення URL-адрес спрацювало б, але довіряючи сертифікату, ви також уникаєте червоного екрана в Internet Explorer, де він говорить, що він не довіряє сертифікату.


11

Якщо ви використовуєте ядро ​​.net, спробуйте це:

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

1
Дякую, це працює. Але це не має нічого спільного з .net core. Це універсальний рецепт :)
Олександр

7

Виконайте такі дії:

  1. Відкрийте посилання служби в IE.

  2. Клацніть на згадці про помилку сертифіката в адресному рядку та натисніть Переглянути сертифікати.

  3. Чек видано на: ім'я.

  4. Візьміть видане ім’я та замініть згадку localhost в службі та імені базової кінцевої точки клієнта на повністю кваліфіковане доменне ім’я (FQDN).

Наприклад: https: // localhost : 203 / SampleService.svc До https: // INL-126166.-.groupinfra.com : 203 / SampleService.svc


Чудово, дякую за цю відповідь! Вирішено проблеми, не змінюючи код.
Випін Дубей

6

Окрім наведених вище відповідей, ви можете зіткнутися з цією помилкою, якщо ваш клієнт працює неправильною версією TLS, наприклад, якщо на сервері працює лише TLS 1.2.

Ви можете виправити це за допомогою:

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

у моєму випадку прийнята відповідь мені не допомогла, але цей зробив трюк
Сергій

Це єдина відповідь, яка виправила помилку в моєму випадку.
Тольга

5

У мене була така ж проблема. Я також додав сертифікати CA у місцевому магазині, але я це зробив WRONG.

За допомогою консолі mmc (Пуск -> Запуск -> mmc ) слід додати оснащення сертифікатів як обліковий запис Сервісу (вибір облікового запису служби IIS) або Обліковий запис комп'ютера (додається для кожного облікового запису на машині)

Ось зображення того, про що я говорю Додайте оснащення для облікового запису послуги чи облікового запису комп’ютера

З цього моменту ви можете додати сертифікати ЦС ( довірених кореневих ЦЗ та проміжних ЦО ), і все буде добре


4

У мене був аналогічний випуск із самовільним підписом. Я можу це вирішити, використовуючи ім'я сертифіката, таке ж, як FQDN сервера.

В ідеалі частиною SSL слід керувати на стороні сервера. Клієнт не вимагає встановлення будь-якого сертифіката для SSL. Також деякі згадані публікації про обхід SSL з коду клієнта. Але я абсолютно не згоден з цим.


3

Я просто перетягнув сертифікат у папку "Довірені кореневі органи сертифікації" і вуалі все добре працював.

Ой. І я спершу додав таке з командного рядка адміністратора:

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

Я не впевнений у тому, яке ім’я вам потрібно користувачеві (моє норвезьке, як ви бачите!) user=NT-AUTHORITY/INTERACTIVE:?

Ви можете побачити всі існуючі urlacl, видавши команду: netsh http show urlacl


0

Це сталося при спробі підключення до служби WCF через. IP, наприклад, https://111.11.111.1:port/MyService.svcпід час використання сертифіката, прив'язаного до імені, наприклад, mysite.com.

Перехід до https://mysite.com:port/MyService.svcвирішеного.


0

Це сталося під час спроби підключитися до служби WCF, використовуючи лише ім'я хоста, наприклад https: //host/MyService.svc під час використання сертифіката, прив’язаного до імені, наприклад, host.mysite.com.

Перехід на https://host.mysite.com/MyService.svc, і це вирішило.


0

Тільки виправили подібну проблему.

Я зрозумів, що у мене є пул додатків, який працює під обліковим записом, який має лише дозвіл на читання через сертифікат, що він використовується.

Додаток .NET міг правильно отримати сертифікат, але цей виняток було видалено лише тоді, коли було викликано GetRequestStream ().

Дозволами сертифікатів можна керувати через консоль MMC


0

Якщо ви використовуєте ядро ​​.net, то під час розробки ви можете обійти перевірку сертифікатів за допомогою директив компілятора. Цей спосіб підтверджує лише сертифікат для випуску, а не для налагодження:

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

-6

Додайте це до коду клієнта:

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

4
Ця відповідь не дуже гарна, оскільки не пояснює ризики, пов'язані з кодом.
daveD
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.