SSL / TLS 보안 채널 (SOAP)에 대한 신뢰 관계를 설정할 수 없습니다.


325

C # (2.0)으로 작성된 웹 서비스에 대해 Visual Studio에서 생성 된 웹 서비스 프록시를 통해 .NET (C #) 2.0 Windows 앱으로 생성 된 간단한 웹 서비스 호출이 있습니다. 이것은 몇 년 동안 일해 왔으며, 수십 개나 그 곳에서 계속 작동하고 있습니다.

새 사이트에서 새로 설치하면 문제가 발생합니다. 웹 서비스를 호출하려고 시도하면 다음과 같은 메시지와 함께 실패합니다.

SSL / TLS 보안 채널에 대한 신뢰 관계를 설정할 수 없습니다

웹 서비스의 URL은 SSL (https : //)을 사용하지만 다른 여러 위치에서 오랫동안 작동 해 왔습니다.

어디에서 보입니까? 이 설치에 고유 한 Windows와 .NET 간의 보안 문제 일 수 있습니까? 그렇다면 신뢰 관계를 어디에 설정합니까? 나는 길을 잃었다!


필자의 경우이 오류는 IP 주소 전달로 인해 발생했습니다.
— cja

답변:


166

생각 (과거의 고통에 근거) :

  • 서버에 대한 DNS 및 가시선이 있습니까?
  • 인증서에서 올바른 이름을 사용하고 있습니까?
  • 인증서가 여전히 유효합니까?
  • 잘못 구성된로드 밸런서가 엉망입니까?
  • 새 서버 시스템에 시계가 올바르게 설정되어 있습니까 (즉, UTC 시간이 정확하도록 [현지 시간 무시, 크게 영향을받지 않음]) 이것은 확실히 WCF에 중요하므로 일반 SOAP에 영향을 줄 수 있습니까?
  • 인증서 신뢰 체인 문제가 있습니까? 서버에서 SOAP 서비스를 탐색하면 SSL을 얻을 수 있습니까?
  • 위와 관련된-인증서가 올바른 위치에 설치 되었습니까? (신뢰할 수있는 루트 인증 기관에 사본이 필요할 수 있습니다)
  • 서버의 머신 레벨 프록시가 올바르게 설정되어 있습니까? (사용자의 프록시와 다릅니다); XP / 2003 용 proxycfg를 참조하십시오 (Vista 등에 대해서는 확실하지 않음)

2
1) 웹 서비스가 웹에 있습니다. 브라우저를 통해 찾아 볼 수 있습니다. 2) 새 컴퓨터는 서버가 아닙니다. 주문 정보를 수집하고 SOAP 서비스를 통해 업로드하는 내 앱을 실행하는 데스크톱입니다. 3) 예, 찾아 볼 수 있습니다. 4) 이것은 기계 수준 프록시입니까?
— Rob Schripsema

2
예; 코드는 IE 프록시 설정을 사용하지 않습니다. 별도의 저장소를 사용합니다 (프록시를 사용하는 경우). XP에서 가장 쉬운 옵션은 IE 설정을 가져 오는 (IIRC) "proxycfg -i"입니다.
— Marc Gravell

11
고마워 마크. 이것은 나를 도왔으며 문제는 서버가 내가 아직 신뢰할 수없는 타사 CA에 의해 서명 된 인증서를 가지고 있다는 것입니다. 해결책은 해당 CA를 신뢰할 수있는 루트 CA 목록에 추가하는 것입니다.
— p.campbell 2009

1
이 예외가 발생한 컴퓨터는 시간 서버를 사용하여 시스템 시간을 동기화 할 수 없습니다. 작동하기 전에 시간을 수동으로 동기화해야했습니다.
— Chris-Haddox Technologies

4
Fiddler를 사용하여 서비스 호출을 디버그하고 인증서 차단 모드를 사용한 경우이 정보를 얻을 수 있습니다. 피들러의 옵션에서 가로 채기를 제거하면 좋을 것입니다
— Ruskin

363

다음 스 니펫은 호출중인 서버의 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;
}

6
ServicePointManager에 대한 나의 경험. 변경하면 전체 앱 도메인에 영향을 미칩니다. 대답은 이것이 어떻게 적용될 수 있는지 매우 명확하게 설명되어 있지만이 점을 던지는 것을 좋아합니다.
— Amzath

콜백 설정은 .NET 4.5에서는 작동하지만 .NET 4.6에서는 작동하지 않습니다.
— RJB

@Amzath 특정 요청이 완료된 후이를 재설정하는 방법에 대한 제안 사항이 있습니까? 인증되지 않은 서버에 한 번 요청한 다음 원래 상태로 되돌려 놓아야 할 수도 있습니다.
— Isaac Lyman

1
@Isaac Lyman : ServicePointManager.ServerCertificateValidationCallback = null;기본 동작으로 되돌려 야합니다.
— Mike Chamberlain

1
@MikeChamberlain 제안의 유일한 문제는 전역 앱 설정을 처리하기 때문에 동시 요청이 안전하지 않을 수 있다는 것입니다.
— Isaac Lyman

178

매우 간단한 "모두 포착"솔루션은 다음과 같습니다.

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

sebastian-castaldi의 솔루션이 조금 더 자세합니다.


21
방금 이것을 #If CONFIG = "Debug"명령문에 넣으면 디버그 모드에서만 활성화됩니다. 잘 작동합니다!
— cjbarth

1
세부 사항은 좋을 수 있지만 빠르고, 짧고, 쉬운 코드 줄에 대해서도 언급해야합니다. 이 코드는 짧고 트릭을 수행합니다.
— allen1

이 작업은 현재 작업에서만 작동합니까 (예 : ASP MVC 사용)? 아니면 ASP.NET 응용 프로그램의 기본 동작으로 설정됩니까?
— JeeShen Lee

2
이것은 테스트 목적으로 만 사용해야하며,이 솔루션은 유효하지
— 않거나

1
위의 설명에서 설명한 것처럼 SSL 연결이 더 이상 유효한지 확인하지 않습니다. 따라서 시스템과 다른 시스템 간의 연결이 손상 될 수 있습니다. 항상 필요한 것이 무엇인지에 대한 질문입니다.
— 레미

35

나는 개인적으로 다음 솔루션을 가장 좋아합니다.

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

... 오류를 요청하기 전에 다음을 수행하십시오.

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

Luke의 솔루션에 문의 한 후 이것을 찾았습니다


4
이 접근법에 대한 보안 경고에 대해서는 Sebastian Castaldi의 답변을 참조하십시오 .
— Edward Brey

프로덕션 환경에서이를 사용할 때의 보안 위험은 무엇입니까?
— Amjad

@Amjad의 보안 위험은 SSL / TLS 사용의 이점을 완전히 회피한다는 것입니다. 서버는 좋아하는 인증서를 제시 할 수
— 1800 INFORMATION

18

Windows 2003을 사용하는 경우 다음을 시도하십시오.

Microsoft 관리 콘솔을 엽니 다 (시작-> 실행-> mmc.exe).

파일-> 스냅인 추가 / 제거를 선택하십시오.

독립형 탭에서 추가를 선택하십시오.

인증서 스냅인을 선택하고 추가를 클릭하십시오.

마법사에서 컴퓨터 계정을 선택한 다음 로컬 컴퓨터를 선택하십시오. 완료를 눌러 마법사를 종료하십시오.

스냅인 추가 / 제거 대화 상자를 닫습니다.

인증서 (로컬 컴퓨터)로 이동하여 가져올 상점을 선택하십시오.

인증서를 발행 한 회사의 루트 CA 인증서가있는 경우 신뢰할 수있는 루트 인증 기관을 선택하십시오.

서버 자체에 대한 인증서가있는 경우 기타 사용자를 선택하십시오.

상점을 마우스 오른쪽 단추로 클릭하고 모든 태스크-> 가져 오기를 선택하십시오.

마법사를 따라 인증서 파일을 제공하십시오.

그런 다음 IIS를 다시 시작하고 웹 서비스를 다시 호출하십시오.

참조 : http://www.outsystems.com/NetworkForums/ViewTopic.aspx?Topic=Web-Services:-Could-not-establish-trust-relationship-for-the-SSL/TLS- ...


2
이것은 나에게 도움이되었지만 신뢰할 수있는 루트 인증 기관 섹션에 인증서가 있어야 작동했습니다. 당으로 blogs.msdn.com/b/jpsanders/archive/2009/09/16/...
— 야곱이 월드

17

맹목적으로 모든 사람을 믿지 않고 특정 호스트에 대해서만 신뢰 예외를 만들지 않으려면 다음 솔루션이 더 적합합니다.

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를 호출하십시오.


@thelem 예 다시 읽기 나는 처음으로 잘못 읽었어야한다고 생각합니다
— Shiv

프로덕션 환경에서 모든 인증서를 신뢰할 수있는 보안 위험은 무엇입니까?
— Amjad

@Amjad의 보안 위험은 클라이언트와 서버 사이의 모든 사람이 통신 도중에 자신을 삽입하고 자체 SSL 인증서를 사용하며 클라이언트와 서버 사이의 모든 트래픽을 읽을 수 있다는 것입니다. 이렇게하면 효과적으로 SSL이 무효화됩니다.
— Rob Prouse

WCF addon을 사용하여 wsdl에서 클래스를 생성 할 때 작동해야합니까?
— Kamil

7

누가는 이것에 대해 꽤 좋은 기사를 썼습니다.

누가의 해결책

이유 (자신의 기사에서 인용 (마이너스 빼기)) ".. 위 코드의 문제점은 인증서가 유효하지 않으면 작동하지 않는다는 것입니다. 왜 SSL 인증서를 사용하여 웹 페이지에 게시하고 SSL 인증서가 유효하지 않습니까? 나는 싸고 나는 Verisign이나 다른 **- * s를 인증서 상자에 내 테스트 상자에 지불하고 싶지 않아서 자체 서명했다. 요청을 보낼 때 나는 멋진 예외를 받았다.

System.Net.WebException 기본 연결이 닫혔습니다. 원격 서버와의 신뢰 관계를 설정할 수 없습니다.

나는 당신에 대해 모른다.하지만 나에게 예외는 내 코드에서 바보 같은 실수로 인해 POST가 실패하는 것처럼 보였습니다. 그래서 나는 계속해서 검색하고, 모든 종류의 이상한 일을 조정하고했습니다. 내가 *** n 일을 검색 한 후에 만 ​​잘못된 SSL 인증서가 발생한 후의 기본 동작은이 예외를 던지는 것임을 알았습니다. .. "


1
이 솔루션은 .Net 4.5에서 더 이상 사용되지 않습니다. 모든 인증서를 수락하려면 아래에서 Sebastian Castaldi 또는 내 답변을 참조하십시오.
— 레미


3

방금이 문제가 발생했습니다. 내 해결책은 시간 서버와 수동으로 동기화하여 시스템 시간을 업데이트하는 것이 었습니다. 이를 위해 다음을 수행 할 수 있습니다.

  • 작업 표시 줄에서 시계를 마우스 오른쪽 버튼으로 클릭
  • 고르다 Adjust Date/Time
  • Internet Time탭을 선택 하십시오
  • 딸깍 하는 소리 Change Settings
  • 고르다 Update Now

제 경우에는 이것이 잘못 동기화되어 올바르게 업데이트되기 전에 여러 번 클릭해야했습니다. 계속 잘못 업데이트되면 서버 드롭 다운에서 다른 시간 서버를 사용해 볼 수도 있습니다.


이런 젠장. 이 정확한 것에 부딪쳤다. 쉬운 수정에 감사드립니다!
— TheGerm

3

이 시도:

System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;

4.5 .NET 프레임 워크 이상으로 작업해야합니다.


3

.NETInternet Explorer의 앱에서도 비슷한 문제가 발생했습니다 .

신뢰할 수있는 편집자 인증서에 인증서 (필자의 경우 VeriSign 클래스 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

감사


1

URL과 같은 웹 서버에 대해이 오류가 발생했습니다.

a.b.domain.com

하지만 인증서가 없어서 DNS라는

a_b.domain.com

이 솔루션은 Google에서 최고이기 때문에 여기에 힌트를 드리겠습니다.


필자의 경우 웹 사이트는 와일드 카드 SSL 인증서 (* .abcd.com)로 구성되었습니다. 웹 사이트 바인딩을 구성했을 때 xyz-abcd.com과 유사하여 문제가 발생했습니다.
— sree jan

1

VS 클라이언트 측을 통해이 문제가 발생하면 서비스 참조를 성공적으로 추가하고 첫 번째 호출을 실행하려는 경우 "기본 연결이 닫혔습니다. SSL / TLS 보안 채널에 대한 트러스트 관계를 설정할 수 없습니다"라는 예외가 발생했습니다. IP 주소와 함께 엔드 포인트 URL을 사용하고 있으며이 예외가 발생하면 다음 단계를 수행하여 서비스 참조를 다시 추가해야합니다.

  • Internet Explorer에서 엔드 포인트 URL을여십시오.
  • 인증서 오류를 클릭하십시오 (주소 표시 줄의 빨간색 아이콘)
  • 인증서보기를 클릭하십시오.
  • 발급 된 "name"을 잡고 IP 주소 또는 사용중인 이름을 바꾸고이 "name"에 대한 오류가 발생합니다.

다시 시도하십시오 :). 감사


0

필자의 경우 IIS 7을 사용하여 Visual Studio 환경에서 SSL 을 테스트하려고했습니다 .

이것이 내가 작동하게하는 일입니다.

  • IIS의 오른쪽에있는 'Bindings ...'섹션에있는 내 사이트에서 포트 443에 'https'바인딩을 추가하고 "IIS Express Developement Certificate"를 선택해야했습니다.

  • 오른쪽의 '고급 설정 ...'섹션에있는 내 사이트에서 '사용 프로토콜'을 "http"에서 "https"로 변경해야했습니다.

  • 'SSL 설정'아이콘에서 클라이언트 인증서에 대해 '동의'를 선택했습니다.

  • 그런 다음 앱 풀을 재활용해야했습니다.

  • 또한 mmc.exe를 사용하여 로컬 호스트 인증서를 개인 저장소로 가져와야했습니다.

내 web.config파일이 이미 올바르게 구성되었으므로 위의 모든 항목을 정렬 한 후에 테스트를 계속할 수있었습니다.


web.config는 어떻게 구성 되었습니까?
— Chazt3n

@ Chazt3n 나는 당신에게 말할 수 없었습니다. 그것은 오래 전이지만 기본 http 바인딩 설정 일 것입니다. 일반적으로 svcutil을 사용하여 웹 서비스 클라이언트 정보에 대한 구성 정보를 생성합니다.
— Popo

0

내 솔루션 (VB.Net,이 응용 프로그램의 "스테이징"(UAT) 버전은 "스테이징"인증서와 함께 작동해야하지만 요청이 라이브 사이트에 있으면 요청에는 영향을 미치지 않아야 함) :

    ...
        Dim url As String = ConfigurationManager.AppSettings("APIURL") & "token"
        If url.ToLower().Contains("staging") Then
           System.Net.ServicePointManager.ServerCertificateValidationCallback = AddressOf AcceptAllCertifications
        End If
    ...

    Private  Function AcceptAllCertifications(ByVal sender As Object, ByVal certification As System.Security.Cryptography.X509Certificates.X509Certificate, ByVal chain As System.Security.Cryptography.X509Certificates.X509Chain, ByVal sslPolicyErrors As System.Net.Security.SslPolicyErrors) As Boolean
        Return True
    End Function

-3

ServerCertificateValidationCallback이 true를 반환 할 때 잘못된 sertificate가 작동하지 않으면; 내 서버 인증서 ValidationCallback 코드 :

ServicePointManager.ServerCertificateValidationCallback += delegate
{
    LogWriter.LogInfo("Проверка сертификата отключена, на уровне ServerCertificateValidationCallback");
    return true;
};

ServerCertificateValidationCallback을 실행하지 못하게하는 코드 :

     if (!(ServicePointManager.CertificatePolicy is CertificateValidation))
    {
        CertificateValidation certValidate = new CertificateValidation();
        certValidate.ValidatingError += new CertificateValidation.ValidateCertificateEventHandler(this.OnValidateCertificateError);
        ServicePointManager.CertificatePolicy = certValidate;
    }

OnValidateCertificateError 함수 :

private void OnValidateCertificateError(object sender, CertificateValidationEventArgs e)
{
    string msg = string.Format(Strings.OnValidateCertificateError, e.Request.RequestUri, e.Certificate.GetName(), e.Problem, new Win32Exception(e.Problem).Message);
    LogWriter.LogError(msg);
    //Message.ShowError(msg);
}

CertificateValidation 코드와 ServerCertificateValidationCallback이 매우 잘 실행되지 않도록 설정했습니다.


인증서 유효성 검사를 비활성화하지 마십시오. 대신 유효성 검사에 실패하는 문제를 해결하십시오.
— Dan

프로덕션 환경에서이를 사용할 때의 보안 위험은 무엇입니까?
— Amjad
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.