원격 당사자가 전송 스트림을 닫았 기 때문에 인증에 실패했습니다.


87

인증서 인증으로 OpenSSL 서버를 연결하는 TCP 클라이언트를 개발 중입니다. 서버 팀에서 공유하는 .crt 및 .key 파일을 사용하고 있습니다. 이러한 인증서는 OpenSSL 명령에 의해 생성됩니다.

내가 사용하고 SslStream호출하여 TCP 클라이언트를 인증하는 개체를 SslStream.AuthenticateAsClient서버에 전달하여 방법을 IP, SslProtocols.Ssl3하고 X509CertificateCollection.

다음과 같은 오류가 발생합니다.

원격 당사자가 전송 스트림을 닫았 기 때문에 인증에 실패했습니다.


2
이것은 POODLE 이후의 문제인 것 같습니다 : SslProtocols.Ssl3. 아마 당신은 시도해야합니다 SslProtocols.Tls. .Net 4.5 이상에서는 Tls11또는 Tls12. SslProtocols 열거를 참조하십시오 . 다른 문제가있을 수 있습니다.
jww


감사. 내 문제는 Windows 인증서 저장소에서 인증서 주체 이름을 검색하는 대신 인증서 및 암호의 실제 경로에서 인증서를 첨부하여 해결됩니다.
Odelu

이제 모든 SslProtocols (SSL3, Tls1 및 Tls2)에서 결과를 얻을 수 있습니다. 답장 해
주셔서

@Odelu, 어떻게 문제를 해결 했습니까? 클라이언트 측 또는 서버 측?

답변:


155

SecurityProtocol을 TLS 1.1로 제한하지 않는 것이 좋습니다.

권장되는 해결책은

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls

또 다른 옵션은 다음 레지스트리 키를 추가하는 것입니다.

Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 
Value: SchUseStrongCrypto 

.NET 4.6은 기본적으로 올바른 프로토콜을 사용하며 두 솔루션 모두 필요하지 않습니다.


6
와우, 당신은 방금 내 문제를 정리했습니다.-저는 모든 종류의 일을 시도하고있었습니다-그리고 결국 여기에서 프레임 워크에 대한 메모를 보았습니다. 프레임 워크가 잘못된 보안 프로토콜을 사용하고있을 수 있기를 바라며 4.6.1 (4.5 사용)으로 전환했습니다.
Veverke

7
System.Net.ServicePointManager.SecurityProtocol = ...요청을 작성하기 전에 실행해야 한다고 말하는 것이 중요합니다 .
Tonatio

2
4.6.1 로의 타겟 프레임 워크 버전 업데이트가 내 생명을 구했습니다 :-)
Awais

내 프레임 워크는 4.6.2로 설정되어 있습니다. 어쩌면 내가 대신 TLS 솔루션을 사용해야합니다
발광

4.7.2 Framework를 사용하고 있습니다. 요청을 보내는 사이트도 TLS 1.2를 사용하고 있지만 10에서 6 번 요청하면이 오류가 발생합니다. 어떤 아이디어?
Davit Mikuchadze

16

이전 버전의 .net을 사용하려면 고유 한 플래그를 만들고 캐스팅합니다.

    //
    // Summary:
    //     Specifies the security protocols that are supported by the Schannel security
    //     package.
    [Flags]
    private enum MySecurityProtocolType
    {
        //
        // Summary:
        //     Specifies the Secure Socket Layer (SSL) 3.0 security protocol.
        Ssl3 = 48,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.0 security protocol.
        Tls = 192,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.1 security protocol.
        Tls11 = 768,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.2 security protocol.
        Tls12 = 3072
    }
    public Session()
    {
        System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)(MySecurityProtocolType.Tls12 | MySecurityProtocolType.Tls11 | MySecurityProtocolType.Tls);
    }

1
당신은 당신의 자신의 클래스를 사용하지 않아도, 직접 SecurityProtocolType에 정수를 캐스팅 할 수 있습니다ServicePointManager.SecurityProtocol = (SecurityProtocolType) 48 | (SecurityProtocolType) 192 | (SecurityProtocolType) 768 | (SecurityProtocolType) 3072;
얀 F.

13

아래 코드를 추가하면 문제를 극복하는 데 도움이되었습니다.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;

8
using (var client = new HttpClient(handler))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
                var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, apiEndPoint)).ConfigureAwait(false);
                await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            }

이것은 나를 위해 일했습니다.


1
중요한 비트는 다음 줄입니다. ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; 이 답변은 일반적인 사용 사례에서 해당 라인이 어디에 적합해야하는지 보여주기 때문에 훌륭합니다.
Nick Painter

5

ChargifyNET.dll을 사용하여 Chargify API와 통신하는 동안 동일한 오류 메시지가 나타납니다. chargify.ProtocolType = SecurityProtocolType.Tls12;구성에 추가 하면 문제가 해결되었습니다.

다음은 전체 코드 스 니펫입니다.

public ChargifyConnect GetChargifyConnect()
{
    var chargify = new ChargifyConnect();
    chargify.apiKey = ConfigurationManager.AppSettings["Chargify.apiKey"];
    chargify.Password = ConfigurationManager.AppSettings["Chargify.apiPassword"];
    chargify.URL = ConfigurationManager.AppSettings["Chargify.url"];

    // Without this an error will be thrown.
    chargify.ProtocolType = SecurityProtocolType.Tls12;

    return chargify;
}

2

VB.NET의 경우 웹 요청 전에 다음을 배치 할 수 있습니다.

Const _Tls12 As SslProtocols = DirectCast(&HC00, SslProtocols)
Const Tls12 As SecurityProtocolType = DirectCast(_Tls12, SecurityProtocolType)
ServicePointManager.SecurityProtocol = Tls12

이것은 .NET 3.5에서 내 보안 문제를 해결했습니다.


0

웹 요청 엔드 포인트가 TLS1.2 요청 만 허용하는 다른 서버로 전환되었을 때 이런 일이 발생했습니다. 주로 Stackoverflow에서 찾은 많은 시도를 시도했습니다.

  1. 레지스트리 키,
  2. 추가 :
    System.Net.ServicePointManager.SecurityProtocol | = System.Net.SecurityProtocolType.Tls12; Global.ASX OnStart로,
  3. Web.config에 추가되었습니다.
  4. .Net 프레임 워크를 4.7.2로 업데이트했지만 여전히 동일한 예외가 발생합니다.

받은 예외는 내가 직면 한 실제 문제를 정당화하지 못했고 서비스 운영자의 도움을 찾지 못했습니다.

이 문제를 해결하기 위해 새로운 Cipher Suite TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 를 추가 해야 합니다. 아래 그림과 같이 여기 에서 IIS Crypto 2.0 Tool을 사용했습니다 .

여기에 이미지 설명 입력

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.