.NET Framework를 사용한 TLS(전송 계층 보안) 모범 사례

참고 항목

이 페이지에는 .NET Framework TLS 정보가 포함되어 있습니다. .NET TLS 정보를 찾고 있다면 TLS/SSL 모범 사례를 참조하세요.

.NET Framework는 TLS(전송 계층 보안) 프로토콜을 사용하여 네트워크 통신을 보호하는 것을 지원합니다.

TLS(전송 계층 보안)란?

Warning

TLS 1.0 및 1.1은 더 이상 사용되지 않습니다(RFC8996). 이 문서에서는 TLS 1.2 및 TLS 1.3만 다룹니다.

TLS(전송 계층 보안) 프로토콜은 인터넷을 통해 전달되는 정보의 개인 정보를 보호하도록 설계된 업계 최신 버전의 표준입니다. TLS 1.3은 이전 버전보다 향상된 보안을 제공하는 표준입니다. 이 문서에서는 TLS 프로토콜을 사용하는 .NET Framework 애플리케이션을 보호하기 위한 권장 사항을 제공합니다.

이 문서의 도움을 받을 사용자는 누구인가요?

.NET Framework의 TLS 지원

.NET Framework는 Windows에서 Schannel에 종속되므로 협상할 수 있는 버전과 사용되는 버전은 운영 체제에 따라 다릅니다.

다음은 운영 체제 버전과 .NET Framework 대상 버전의 다양한 조합에 대해 지원되는 가장 높은 TLS 버전을 보여 주는 업데이트된 테이블 예입니다.

.NET Framework 대상 버전 Windows 10 Windows 11
3.5 TLS 1.2 TLS 1.2
4.6.2 TLS 1.2 TLS 1.3
4.7 TLS 1.2 TLS 1.3
4.7.1 TLS 1.2 TLS 1.3
4.7.2 TLS 1.2 TLS 1.3
4.8 TLS 1.2 TLS 1.3
4.8.1 TLS 1.2 TLS 1.3

자세한 내용은 Schannel의 TLS 프로토콜 버전 지원을 참조하세요.

권장 사항

  • TLS 1.3의 경우 .NET Framework 4.8 이상을 대상으로 합니다.
  • TLS 버전을 명시적으로 지정하지 마세요. OS에서 TLS 버전을 결정하도록 코드를 구성합니다.
  • 철저한 코드 감사를 수행하여 TLS 또는 SSL 버전을 명시적으로 지정하지 않았는지 확인합니다.
  • SslProtocols.Default는 사용하지 마세요. (SslProtocols.Default는 더 이상 사용되지 않는 SSL3 및 TLS1.0 버전을 지정합니다.)

앱에서 OS가 TLS 버전을 선택하도록 하는 경우:

  • 향후 추가되는 새로운 프로토콜을 자동으로 활용합니다.
  • OS는 검색되지 않는 OS 프로토콜을 차단합니다.

코드 감사 및 변경 섹션에서는 코드를 감사하고 업데이트하는 방법을 설명합니다.

이 문서에서는 앱이 대상으로 하고 실행되는 버전의 .NET Framework에 대해 사용 가능한 가장 강력한 보안을 구현하는 방법을 설명합니다. 명시적으로 보안 프로토콜 및 버전을 설정하는 앱은 다른 대체 방법을 옵트아웃(opt out)하고 .NET Framework 및 OS 기본 동작을 옵트아웃(opt out)합니다. 앱이 TLS 1.3 연결을 협상할 수 있도록 하려는 경우 명시적으로 더 낮은 TLS 버전으로 설정하면 TLS 1.3 연결이 차단됩니다.

프로토콜 버전을 명시적으로 지정하는 것을 피할 수 없다면 TLS1.2 또는 TLS 1.3(currently considered secure)을 지정하는 것이 좋습니다. TLS 1.0 종속성을 식별하고 제거하는 방법에 대한 지침은 TLS 1.0 문제 해결 백서를 다운로드합니다.

WCF는 .NET Framework 4.7에서 TLS 1.2를 기본값으로 지원합니다. .NET Framework 4.7.1부터 WCF 기본값은 운영 체제에 구성된 버전으로 설정됩니다. 애플리케이션이 명시적으로 SslProtocols.None으로 구성된 경우 WCF는 NetTcp 전송을 사용할 때 운영 체제 기본 설정을 사용합니다.

GitHub 문제 .NET Framework를 사용한 TLS(전송 계층 보안) 모범 사례에서 이 문서에 대한 질문을 할 수 있습니다.

코드 감사 및 변경

ASP.NET 애플리케이션의 경우 web.config<system.web><httpRuntime targetFramework> 요소를 검사하여 .NET Framework의 대상 지정 버전을 사용하고 있는지 확인합니다.

Windows Forms 및 기타 애플리케이션의 경우 방법: 한 버전의 .NET Framework를 대상으로 지정을 참조하세요.

다음 섹션을 사용하여 특정 TLS 또는 SSL 버전을 사용하지 않는지 확인합니다.

보안 프로토콜을 명시적으로 설정해야 하는 경우

.NET 또는 OS가 보안 프로토콜을 선택하도록 하는 대신 보안 프로토콜을 명시적으로 설정해야 하는 경우 다음 프로토콜을 선택합니다.

  • .NET Framework 3.5의 경우: TLS 1.2
  • .NET Framework 4.6.2 이상의 경우: TLS 1.3

열거형에서 지정된 프로토콜을 찾을 수 없는 경우 해당 프로토콜을 확장 파일로 추가할 수 있습니다. 아래 내용을 참조하세요.

SslProtocolExtensions.cs

namespace System.Security.Authentication
{
    public static class SslProtocolsExtensions
    {
        // For .NET Framework 3.5
        public const SslProtocols Tls12 = (SslProtocols)3072;
        // For .NET Framework 4.6.2 and later
        public const SslProtocols Tls13 = (SslProtocols)12288;
    }
}

SecurityProtocolExtensions.cs

using System.Security.Authentication;

namespace System.Net
{
    public static class SecurityProtocolTypeExtensions
    {
        // For .NET Framework 3.5
        public const SecurityProtocolType Tls12 = (SecurityProtocolType)SslProtocolsExtensions.Tls12;
        // For .NET Framework 4.6.2 and later
        public const SecurityProtocolType Tls13 = (SecurityProtocolType)SslProtocolsExtensions.Tls13;
    }
}

자세한 내용은 Windows 8.1 및 Windows Server 2012 R2 기반 .NET Framework 3.5에 포함된 TLS 시스템 기본 버전에 대한 지원을 참조하세요.

System.Net API용(HttpClient, SslStream)

앱이 .NET Framework 4.7 이상 버전을 대상으로 하는 경우

다음 섹션에서는 TLS의 currently considered secure versions를 사용하도록 애플리케이션을 구성하는 방법을 보여 줍니다. (TLS 1.2, TLS 1.3)

HttpClient 및 HttpWebRequest의 경우

.NET Framework 4.7 이상 버전을 사용하는 ServicePointManager는 OS에 구성된 기본 보안 프로토콜을 사용합니다. 기본 OS가 최적의 선택을 하도록 하려면(가능한 경우) ServicePointManager.SecurityProtocol 속성의 값(기본값은 SecurityProtocolType.SystemDefault)을 설정하지 마세요.

SecurityProtocolType.SystemDefault 설정으로 인해 ServicePointManager가 운영 체제에서 구성한 기본 보안 프로토콜을 사용하므로 애플리케이션이 실행되는 OS에 따라 다르게 실행될 수 있습니다. 예를 들어, Windows 10은 TLS 1.2를 사용하고 Windows 11은 TLS 1.3을 사용합니다.

SSLStream의 경우

.NET Framework 4.7 이상 버전을 사용하는 SslStream는 가장 적합한 보안 프로토콜 및 버전을 선택하는 OS로 기본 설정됩니다. 기본 OS가 최적의 선택을 하도록 하려면(가능한 경우) 명시적 SslProtocols 매개 변수를 사용하는 SslStream의 메서드 오버로드를 사용하지 마세요. 그렇지 않으면 SslProtocols.None을 전달합니다. Default를 사용하지 않는 것이 좋습니다. SslProtocols.Default를 설정하면 SSL 3.0/TLS 1.0이 강제로 사용되고 TLS 1.2가 차단됩니다.

SecurityProtocol 속성의 값을 설정하지 마세요(HTTP 네트워킹의 경우).

명시적 SslProtocols 매개 변수를 사용하는 SslStream의 메서드 오버로드를 사용하지 마세요(TCP 소켓 네트워킹의 경우). 앱의 대상을 .NET Framework 4.7 이상 버전으로 변경하면 모범 사례 권장 사항을 따르게 됩니다.

WCF 애플리케이션의 경우

앱이 .NET Framework 4.7 이상 버전을 대상으로 하는 경우

다음 섹션에서는 TLS의 currently considered secure versions를 사용하도록 애플리케이션을 구성하는 방법을 보여 줍니다. (TLS 1.2, TLS 1.3)

인증서 자격 증명과 함께 전송 보안을 사용하여 TCP 전송 사용

WCF는 나머지 .NET Framework와 동일한 네트워킹 스택을 사용합니다.

4.7.1을 대상으로 지정하면 다음 위치에 명시적으로 구성되지 않은 경우에 한해 WCF는 OS에서 기본적으로 가장 적합한 보안 프로토콜을 선택할 수 있도록 구성됩니다.

  • 애플리케이션 구성 파일.
  • 또는소스 코드의 애플리케이션.

기본적으로 .NET Framework 4.7 이상 버전은 TLS 1.2를 사용하고 TLS 1.1 또는 TLS 1.0을 사용한 연결을 허용하도록 구성됩니다. SslProtocols.None을 사용하도록 바인딩을 구성하여 OS가 가장 적합한 보안 프로토콜을 선택할 수 있도록 WCF를 구성하세요. 이 구성은 SslProtocols에서 설정할 수 있습니다. SslProtocols.NoneTransport에서 액세스할 수 있습니다. NetTcpSecurity.TransportSecurity에서 액세스할 수 있습니다.

사용자 지정 바인딩을 사용하는 경우:

  • SslProtocols.None을 사용하도록 SslProtocols를 설정하여 OS가 가장 적합한 보안 프로토콜을 선택할 수 있도록 WCF를 구성합니다.
  • 또는 구성 경로 system.serviceModel/bindings/customBinding/binding/sslStreamSecurity:sslProtocols와 함께 사용되는 프로토콜을 구성합니다.

사용자 지정 바인딩을 사용하지 않고, 또한 구성을 통해 WCF 바인딩을 설정하는 경우 구성 경로 system.serviceModel/bindings/netTcpBinding/binding/security/transport:sslProtocols와 함께 사용되는 프로토콜을 설정합니다.

인증서 사용자 인증 정보로 메시지 보안 사용

.NET Framework 4.7 이상 버전에서는 기본적으로 SecurityProtocol 속성에 지정된 프로토콜을 사용합니다. AppContextSwitchSwitch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocolstrue로 설정된 경우 WCF는 TLS 1.0까지 가장 적합한 프로토콜을 선택합니다.

앱이 4.7 이전의 .NET Framework 버전을 대상으로 하는 경우

다음 섹션에서는 TLS의 currently considered secure versions를 사용하도록 애플리케이션을 구성하는 방법을 보여 줍니다. (TLS 1.2, TLS 1.3)

인증서 자격 증명과 함께 TCP 전송 보안을 사용하는 .NET Framework 4.6.2 사용

WCF 프레임워크는 프로토콜 버전을 명시적으로 구성하지 않는 한 TLS 1.2까지 사용 가능한 가장 높은 프로토콜을 자동으로 선택합니다. 자세한 내용은 이전 섹션 인증서 자격 증명과 함께 전송 보안을 사용하는 WCF TCP 전송의 경우를 참조하세요.

인증서 자격 증명과 함께 TCP 전송 보안을 사용하는 .NET Framework 3.5 사용

이러한 버전의 WCF 프레임워크는 SSL 3.0 및 TLS 1.0 값을 사용하도록 명시적으로 지정됩니다. 이러한 값은 변경할 수 없습니다. TLS 1.2를 사용하려면 NET Framework 4.6.2 이상 버전으로 업데이트하고 대상을 변경해야 합니다.

AppContext 스위치를 통해 보안 구성(.NET Framework 4.6.2 이상 버전용)

앱이 .NET Framework 4.6.2 이상 버전을 대상으로 하거나 이 버전에서 실행되는 경우 이 섹션에 설명된 AppContext 스위치는 관련이 있습니다. 기본적으로 또는 명시적으로 설정하는지 여부에 관계없이 스위치는 false여야 합니다(가능할 경우). 하나 또는 두 스위치를 통해 보안을 구성하려는 경우 코드에서 보안 프로토콜 값을 지정하지 마세요. 지정할 경우 스위치가 재정의됩니다.

System.Net API용(HttpClient, SslStream)

HTTP 네트워킹(ServicePointManager) 또는 TCP 소켓 네트워킹(SslStream)을 수행하는지에 관계없이 스위치의 효과는 동일합니다.

Switch.System.Net.DontEnableSchUseStrongCrypto

Switch.System.Net.DontEnableSchUseStrongCryptofalse 값이면 앱에서 강력한 암호화가 사용됩니다. DontEnableSchUseStrongCryptofalse 값이면 더 안전한 네트워크 프로토콜(TLS 1.2 및 TLS 1.1)이 사용되고 보안되지 않은 프로토콜은 차단됩니다. 자세한 내용은 SCH_USE_STRONG_CRYPTO 플래그를 참조하세요. true 값은 앱에 대해 강력한 암호화를 사용하지 않도록 설정합니다. 이 스위치는 애플리케이션의 클라이언트(나가는) 연결에만 영향을 줍니다.

앱이 .NET Framework 4.6.2 이상 버전을 대상으로 하는 경우 이 스위치는 기본적으로 false로 설정됩니다. 이 값이 권장되는 안전한 기본값입니다. 앱이 .NET Framework 4.6.2에서 실행되지만 이전 버전을 대상으로 하는 경우 스위치는 기본적으로 true로 설정됩니다. 이 경우 스위치를 명시적으로 false로 설정해야 합니다.

DontEnableSchUseStrongCrypto는 강력한 암호화를 지원하지 않고 업그레이드할 수 없는 레거시 서비스에 연결해야 하는 경우에만 true 값으로 설정되어야 합니다.

Switch.System.Net.DontEnableSystemDefaultTlsVersions

Switch.System.Net.DontEnableSystemDefaultTlsVersionsfalse 값이면 앱에서 운영 체제가 프로토콜을 선택하도록 허용됩니다. true 값이면 앱이 .NET Framework에서 선택된 프로토콜을 사용합니다.

앱이 .NET Framework 4.7 이상 버전을 대상으로 하는 경우 이 스위치는 기본적으로 false로 설정됩니다. 이 값이 권장되는 안전한 기본값입니다. 앱이 .NET Framework 4.7 이상 버전에서 실행되지만 이전 버전을 대상으로 하는 경우 스위치는 기본적으로 true로 설정됩니다. 이 경우 스위치를 명시적으로 false로 설정해야 합니다.

WCF 애플리케이션의 경우

Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols

Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocolsfalse 값이면 애플리케이션에는 인증서 자격 증명을 사용하는 메시지 보안을 위해 ServicePointManager.SecurityProtocols에 정의된 값이 사용됩니다. true 값이면 TLS1.0까지 사용 가능한 최고 버전의 프로토콜이 사용됩니다.

.NET Framework 4.7 이상 버전을 대상으로 하는 애플리케이션의 경우 이 값은 기본적으로 false로 설정됩니다. .NET Framework 4.6.2 이하를 대상으로 하는 애플리케이션의 경우 이 값은 기본적으로 true로 설정됩니다.

Switch.System.ServiceModel.DontEnableSystemDefaultTlsVersions

Switch.System.ServiceModel.DontEnableSystemDefaultTlsVersionsfalse 값이면 운영 체제가 프로토콜을 선택할 수 있도록 기본 구성이 설정됩니다. true 값이면 TLS1.2까지 사용 가능한 최고 버전의 프로토콜로 기본값이 설정됩니다.

.NET Framework 4.7.1 이상 버전을 대상으로 하는 애플리케이션의 경우 이 값은 기본적으로 false로 설정됩니다. .NET Framework 4.7 이하를 대상으로 하는 애플리케이션의 경우 이 값은 기본적으로 true로 설정됩니다.

TLS 프로토콜에 대한 자세한 내용은 완화: TLS 프로토콜을 참조하세요. AppContext 스위치에 대한 자세한 내용은 <AppContextSwitchOverrides> Element를 참조하세요.

Windows 레지스트리를 통해 보안 구성

Warning

레지스트리 키를 설정하면 시스템의 모든 애플리케이션에 영향을 줍니다. 머신에 대한 모든 권한이 있고 레지스트리의 변경 내용을 제거할 수 있는 경우에만 이 옵션을 사용합니다.

하나 또는 두 AppContext 스위치를 모두 설정할 수 없는 경우에는 이 섹션에 설명된 Windows 레지스트리 키와 함께 앱에서 사용하는 보안 프로토콜을 제어할 수 있습니다. 앱이 .NET Framework 3.5에서 실행되거나 구성 파일을 편집할 수 없는 경우 AppContext 스위치 중 하나 또는 둘 다를 사용하지 못할 수도 있습니다. 레지스트리를 사용하여 보안을 구성하려면 코드에서 보안 프로토콜 값을 지정하지 마세요. 지정할 경우 레지스트리 설정이 재정의됩니다.

레지스트리 키의 이름은 해당 AppContext 스위치의 이름과 유사하지만 이름 앞에 DontEnable이 추가되지 않습니다. 예를 들어 AppContext 스위치 DontEnableSchUseStrongCryptoSchUseStrongCrypto라는 레지스트리 키입니다.

이러한 키는 모든 .NET Framework 버전에서 사용할 수 있습니다.

HTTP 네트워킹(ServicePointManager) 또는 TCP 소켓 네트워킹(SslStream)을 수행하는지에 관계없이 아래 설명된 모든 레지스트리 키의 효과는 동일합니다.

SchUseStrongCrypto

HKEY_LOCAL_MACHINE\SOFTWARE\[Wow6432Node\]Microsoft\.NETFramework\<VERSION>: SchUseStrongCrypto 레지스트리 항목에는 DWORD 형식의 값이 있습니다. 값이 1이면 앱에서 강력한 암호화가 사용됩니다. 강력한 암호화는 보다 보안된 네트워크 프로토콜(TLS 1.2 및 TLS 1.1)을 사용하고 안전하지 않은 프로토콜을 차단합니다. 0 값은 강력한 암호화를 사용하지 않도록 설정합니다. 자세한 내용은 SCH_USE_STRONG_CRYPTO 플래그를 참조하세요. 이 레지스트리 설정은 애플리케이션의 클라이언트(나가는) 연결에만 영향을 줍니다.

앱이 .NET Framework 4.6 이상 버전을 대상으로 하는 경우 이 키는 기본적으로 1 값으로 설정됩니다. 이 값이 권장되는 안전한 기본값입니다. 앱이 .NET Framework 4.5.2 이전 버전을 대상으로 하는 경우 이 키는 기본적으로 0입니다. 이 경우 키 값을 명시적으로 1로 설정해야 합니다.

이 키는 강력한 암호화를 지원하지 않고 업그레이드할 수 없는 레거시 서비스에 연결해야 하는 경우에만 0 값으로 설정되어야 합니다.

SystemDefaultTlsVersions

HKEY_LOCAL_MACHINE\SOFTWARE\[Wow6432Node\]Microsoft\.NETFramework\<VERSION>: SystemDefaultTlsVersions 레지스트리 항목에는 DWORD 형식의 값이 있습니다. 값이 1이면 앱에서 운영 체제가 프로토콜을 선택하도록 허용됩니다. 값이 0이면 앱이 .NET Framework에서 선택된 프로토콜을 사용합니다.

<VERSION>은 v4.0.30319(.NET Framework 4 이상의 경우) 또는 v2.0.50727(.NET Framework 3.5의 경우)이어야 합니다.

앱이 .NET Framework 4.7 이상 버전을 대상으로 하는 경우 이 키는 기본적으로 1 값으로 설정됩니다. 이 값이 권장되는 안전한 기본값입니다. 앱이 .NET Framework 4.6.1 이전 버전을 대상으로 하는 경우 이 키는 기본적으로 0입니다. 이 경우 키 값을 명시적으로 1로 설정해야 합니다.

자세한 내용은 Windows 10 버전 1511 및 Windows Server 2016 Technical Preview 4용 누적 업데이트: 2016년 5월 10일을 참조하세요.

.NET Framework 3.5.1 사용에 대한 자세한 내용은 Windows 7 SP1 및 Server 2008 R2 SP1 기반 .NET Framework 3.5.1에 포함된 TLS 시스템 기본 버전에 대한 지원을 참조하세요.

다음 .REG 파일은 레지스트리 항목과 해당 변형을 가장 안전한 값으로 설정합니다.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v2.0.50727]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

Windows 레지스트리에서 Schannel 프로토콜 구성

클라이언트 및/또는 서버 앱이 협상하는 프로토콜에 대한 세분화된 제어에 레지스트리를 사용할 수 있습니다. 앱의 네트워킹이 Schannel( 보안 채널의 다른 이름)을 거칩니다. Schannel을 구성하여 앱 동작을 구성할 수 있습니다.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols 레지스트리 키로 시작합니다. 해당 키 아래에 TLS 1.2, TLS 1.3 집합의 하위 키를 만들 수 있습니다. 각 하위 키 아래에 하위 키 Client 및/또는 Server를 만들 수 있습니다. ClientServer 아래에 DWORD 값 DisabledByDefault(0 또는 1) 및 Enabled(0 또는 1)를 만들 수 있습니다.

자세한 내용은 TLS 레지스트리 설정 - Schannel을 참조하세요.

SCH_USE_STRONG_CRYPTO 플래그

사용하도록 설정된 경우(기본적으로, AppContext 스위치 또는 Windows 레지스트리에서) .NET Framework는 앱에서 서버에 대한 TLS 연결을 시작할 때 SCH_USE_STRONG_CRYPTO 플래그를 사용합니다. .NET Framework는 플래그를 Schannel에 전달하여 상호 운용성 향상을 위해 사용하도록 설정될 수 있는, 알려진 약한 암호화 알고리즘, 암호 도구 모음 및 TLS/SSL 프로토콜 버전을 사용하지 않도록 설정하도록 지시합니다. 자세한 내용은 다음을 참조하세요.

SCH_USE_STRONG_CRYPTO 플래그는 SecurityProtocolType 또는 SslProtocolsTls11 또는 Tls12 열거 값을 명시적으로 사용하는 경우 클라이언트(발신) 연결에 대해 Schannel에도 전달됩니다. SCH_USE_STRONG_CRYPTO 플래그는 애플리케이션이 클라이언트 역할을 하는 연결에만 사용됩니다. 애플리케이션이 컴퓨터 전체 Schannel 레지스트리 설정을 구성하여 서버 역할을 하는 경우 약한 프로토콜 및 알고리즘을 사용하지 않도록 설정할 수 있습니다.