Не удалось установить доверительные отношения для безопасного канала SSL / TLS - SOAP - PullRequest
307 голосов
/ 01 апреля 2009

У меня есть простой вызов веб-службы, сгенерированный приложением Windows .NET (C #) 2.0, через прокси-сервер веб-службы, сгенерированный Visual Studio, для веб-службы, также написанной на C # (2.0). Это работало в течение нескольких лет и продолжает действовать в дюжине мест, где он работает.

Новая установка на новом сайте сталкивается с проблемой. При попытке вызвать веб-службу происходит сбой с сообщением:

Не удалось установить доверительные отношения для безопасного SSL / TLS канал

В URL-адресе веб-службы используется SSL (https://)), но он давно работает (и продолжает это делать) из многих других мест.

Куда мне смотреть? Может ли это быть проблемой безопасности между Windows и .NET, которая уникальна для этой установки? Если да, то где мне установить доверительные отношения? Я потерян!

Ответы [ 15 ]

347 голосов
/ 07 июля 2011

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

Это опасно , если вы вызываете сервер, находящийся вне вашего прямого контроля, поскольку вы больше не можете быть уверены, что разговариваете с сервером, к которому, как вы думаете, вы подключены. Однако, если вы имеете дело с внутренними серверами и получение «правильного» сертификата нецелесообразно, используйте следующую команду, чтобы сообщить веб-службе, что нужно игнорировать проблемы с сертификатом, и смело идти дальше.

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

//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 = cert.Subject.Contains("YourServerName");
    return result;
}
160 голосов
/ 18 марта 2013

Очень простое решение "поймай все" таково:

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

Решение от Себастьяна-Кастальди немного более детально.

157 голосов
/ 01 апреля 2009

Мысли (основанные на боли в прошлом):

  • есть ли у вас DNS и прямой доступ к серверу?
  • вы используете правильное имя из сертификата?
  • Сертификат еще действителен?
  • плохо настроен балансировщик нагрузки?
  • имеет ли на новом сервере машину часы, установленные правильно (т. Е. Время в формате UTC правильное [игнорировать местное время, оно в значительной степени нерелевантно]) - это, безусловно, важно для WCF, поэтому может влиять SOAP?
  • существует ли проблема цепочки доверия сертификата? если вы переходите с сервера на мыльный сервис, можете ли вы получить SSL?
  • относится к вышесказанному - был ли сертификат установлен в правильном месте? (вам может потребоваться копия в доверенных корневых центрах сертификации)
  • Правильно ли настроен прокси-сервер уровня машины? (который отличается от прокси пользователя); см. proxycfg для XP / 2003 (не уверен насчет Vista и т. д.)
32 голосов
/ 27 февраля 2013

Мне лично больше всего нравится следующее решение:

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

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

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

Обнаружил это после консультации Решение Люка

18 голосов
/ 25 марта 2011

Если вы используете Windows 2003, вы можете попробовать это:

Открыть консоль управления Microsoft (Пуск -> Выполнить -> mmc.exe);

Выберите Файл -> Добавить / Удалить оснастку;

На отдельной вкладке выберите Добавить;

Выберите оснастку «Сертификаты» и нажмите Добавить;

В мастере выберите Компьютер Аккаунт, а затем выберите Локальный Компьютер. Нажмите Finish, чтобы завершить Мастер;

Закрыть диалоговое окно «Добавить / удалить оснастку»;

Перейти к сертификатам (локально Компьютер) и выберите магазин импорт:

Если у вас есть сертификат Root CA для компании, которая выпустила сертификат, выберите Trusted Root Центры сертификации;

Если у вас есть сертификат для сам сервер, выберите Other People

Щелкните магазин правой кнопкой мыши и выберите «Все». Задачи -> Импорт

Следуйте указаниям мастера и предоставьте файл сертификата у вас есть;

После этого просто перезапустите IIS и попробуйте повторный вызов веб-службы.

Ссылка: http://www.outsystems.com/NetworkForums/ViewTopic.aspx?Topic=Web-Services:-Could-not-establish-trust-relationship-for-the-SSL/TLS-...

15 голосов
/ 08 октября 2014

Если вы не хотите слепо доверять всем и делать исключение доверия только для определенных хостов, более подходящим является следующее решение.

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

Затем просто вызовите Ssl.EnableTrustedHosts при запуске вашего приложения.

7 голосов
/ 01 апреля 2009

Microsoft Инструмент диагностики SSL может помочь выявить проблему.

ОБНОВЛЕНИЕ ссылка была исправлена.

6 голосов
/ 25 октября 2012

Люк написал довольно хорошую статью об этом .. довольно прямолинейно .. попробуй

Решение Люка

Причина (цитата из его статьи (минус ругань)) ».. Проблема с кодом выше в том, что он не работает, если ваш сертификат недействителен. Зачем мне публиковать на веб-странице с недействительным сертификатом SSL? Потому что я дешевый и мне не хотелось платить Verisign или одному из других ** - * за сертификат к моей тестовой коробке, поэтому я сам подписал его. Когда я отправил запрос, мне бросили прекрасное исключение:

System.Net.WebException Базовое соединение было закрыто. Не удалось установить доверительные отношения с удаленным сервером.

Я не знаю о вас, но для меня это исключение выглядело как нечто, что было бы вызвано глупой ошибкой в ​​моем коде, которая приводила к сбою POST. Поэтому я продолжал искать, настраивать и делать разные странные вещи. Только после того, как я погуглил, я обнаружил, что поведение по умолчанию после обнаружения недействительного сертификата SSL - это исключение. .. "

3 голосов
/ 25 мая 2015

У меня была похожая проблема в приложении .NET в Internet Explorer.

Я решил проблему добавления сертификата (сертификат VeriSign Class 3 в моем случае) к сертификатам доверенных редакторов.

Go to Internet Options-> Content -> Publishers and import it

Вы можете получить сертификат, если экспортируете его из:

Internet Options-> Content -> Certificates -> Intermediate Certification Authorities -> VeriSign Class 3 Public Primary Certification Authority - G5

спасибо

3 голосов
/ 22 февраля 2013

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

  • Щелкните правой кнопкой мыши часы на панели задач
  • Выбрать Adjust Date/Time
  • Выберите вкладку Internet Time
  • Нажмите Change Settings
  • Выбрать Update Now

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

...