次の方法で共有


.NET Framework でのトランスポート層セキュリティ (TLS) のベスト プラクティス

Note

このページには、.NET Framework の TLS 情報が含まれています。 .NET TLS 情報をお探しの場合は、「TLS/SSL のベスト プラクティス」をご覧ください

.NET Framework では、トランスポート層セキュリティ (TLS) プロトコルを使用する、セキュリティで保護されたネットワーク通信がサポートされています。

トランスポート層セキュリティ (TLS) とは

警告

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 以降を対象とします。 target framework の確認方法については、コードの監査に関するセクションを参照してください。
  • TLS バージョンを明示的に指定しないでください。つまり、明示的な SslProtocols パラメーターを受け取る SslStream のメソッド オーバーロードを使わないでください。
    • こうすることで、コードによって OS が TLS バージョンを決定できるようになります。
    • ServicePointManager.SecurityProtocol を設定する必要がある場合は、SecurityProtocolType.SystemDefault に設定します。 これも OS の既定値を使用します。
    • 明示的な SslProtocols パラメーターを受け取る SslStream のメソッド オーバーロードを使用する必要がある場合は、引数として SslProtocols.SystemDefault を渡します。 これも OS の既定値を使用します。
  • コードの監査を徹底的に実行し、TLS または SSL のバージョンを明示的に指定していないことを確認する。

警告

SslProtocols.Default を使用しないでください。なぜなら、これにより、TLS バージョンが、廃止された SSL3 および TLS 1.0 に設定されるからです。

OS が TLS のバージョンを選ぶようにアプリを構成すると、次のようになります。

  • 将来的に追加される新しい TLS プロトコルを自動的に利用します。
  • OS は、セキュリティで保護されていないことが検出されたプロトコルをブロックします (例: SSL3 および TLS 1.0)。

この記事では、お使いのアプリの実行対象になっている .NET Framework のバージョンで使用できる最も強力なセキュリティを有効にする方法について説明します。 アプリでセキュリティ プロトコルとバージョンを明示的に設定すると、他の選択肢および .NET Framework と OS の既定の動作は使われなくなります。 お使いのアプリで TLS 1.3 接続をネゴシエートできるようにしたい場合、それより低いバージョンの TLS に明示的に設定すると、TLS 1.3 の接続は拒否されます。

プロトコル バージョンを明示的に指定しないことを回避できない場合は、TLS1.2 または TLS 1.3 (つまり currently considered secure) を指定することを強くお勧めします。 TLS 1.0 への依存関係の識別と除去に関するガイダンスについては、ホワイトペーパー「Solving the TLS 1.0 Problem」(TLS 1.0 の問題を解決する) をダウンロードしてください。

WCF は、.NET Framework 4.7 での既定値として TLS 1.2 をサポートしています。 .NET Framework 4.7.1 以降の WCF の既定値は、オペレーティング システムで構成されている TLS のバージョンです。 アプリケーションが SslProtocols.None で明示的に構成されている場合、WCF は、NetTcp トランスポートを使うとき、オペレーティング システムの既定の設定を使います。

このドキュメントに関してわからないことは、GitHub の問題「Transport Layer Security (TLS) best practices with the .NET Framework」(.NET Framework でのトランスポート層セキュリティ (TLS) のベスト プラクティス) で質問できます。

コードの監査および変更を行う

ASP.NET アプリケーションの場合、対象となる意図したバージョンの .NET Framework を使っていることを確認するには、web.config<system.web><httpRuntime targetFramework> 要素を調べます。

Windows フォームやその他のアプリケーションの場合は、「方法:.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 の場合

ServicePointManager で .NET Framework 4.7 以降のバージョンを使用すると、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 での接続を許可するように構成されます。 OS による最適なセキュリティ プロトコルの選択を許可するように WCF を構成するには、SslProtocols.None を使うようにバインドを構成します。 これは SslProtocols で設定できます。 SslProtocols.None には Transport からアクセスできます。 NetTcpSecurity.Transport には Security からアクセスできます。

カスタム バインドを使っている場合:

  • OS による最適なセキュリティ プロトコルの選択を許可するように WCF を構成するには、SslProtocols.None を使うように SslProtocols を設定します。
  • または、構成パス system.serviceModel/bindings/customBinding/binding/sslStreamSecurity:sslProtocols で使われるプロトコルを構成します。

カスタム バインドを使用しておらずかつ、構成を使って WCF バインドを設定している場合は、構成パス system.serviceModel/bindings/netTcpBinding/binding/security/transport:sslProtocols で使われるプロトコルを設定します。

証明書資格情報を使うメッセージ セキュリティを使用する

.NET Framework 4.7 以降のバージョンは、既定で、SecurityProtocol プロパティで指定されているプロトコルを使います。 AppContextSwitch Switch.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 以降のバージョンの場合)

このセクションで説明する AppContext スイッチは、お使いのアプリの対象または実行環境が .NET Framework 4.6.2 以降のバージョンである場合に関係します。 既定によるものか、または明示的な設定によるものかに関係なく、可能な場合にはこれらのスイッチを false にする必要があります。 一方または両方のスイッチでセキュリティを構成する必要がある場合は、コードでセキュリティ プロトコルの値を指定しないでください。指定すると、スイッチの設定はオーバーライドされます。

System.Net API の場合 (HttpClient、SslStream)

HTTP ネットワーク (ServicePointManager) または TCP ソケット ネットワーク (SslStream) のどちらを使っている場合でも、スイッチの効果は同じです。

Switch.System.Net.DontEnableSchUseStrongCrypto

Switch.System.Net.DontEnableSchUseStrongCrypto の値を false に設定すると、アプリは強力な暗号を使うようになります。 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.DontEnableSystemDefaultTlsVersions の値を false に設定すると、お使いのアプリはオペレーティング システムによるプロトコルの選択を許可するようになります。 値を true にすると、アプリは .NET Framework によって選択されたプロトコルを使います。

アプリの対象が .NET Framework 4.7 以降のバージョンの場合、このスイッチの既定値は false です。 これは、推奨されるセキュリティ保護が有効な既定値です。 アプリの実行環境が .NET Framework 4.7 以降のバージョンであっても、以前のバージョンが対象になっている場合は、このスイッチの既定値は true です。 その場合は、false に明示的に設定する必要があります。

WCF アプリケーションの場合

Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols

Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols の値を false に設定すると、お使いのアプリケーションは、証明書資格情報を使うメッセージ セキュリティに対して ServicePointManager.SecurityProtocols で定義されている値を使うようになります。 値が true のときは、TLS1.0 以下で利用可能な最も高いプロトコルを使います。

.NET Framework 4.7 以降のバージョンを対象とするアプリケーションでは、この値の既定値は false です。 .NET Framework 4.6.2 以前のバージョンを対象とするアプリケーションでは、この値の既定値は true です。

Switch.System.ServiceModel.DontEnableSystemDefaultTlsVersions

Switch.System.ServiceModel.DontEnableSystemDefaultTlsVersions の値を false に設定すると、オペレーティング システムによるプロトコルの選択を許可するように既定の構成が設定されます。 値が true のときは、TLS1.2 以下で利用可能な最も高いプロトコルに既定値が設定されます。

.NET Framework 4.7.1 以降のバージョンを対象とするアプリケーションでは、この値の既定値は false です。 .NET Framework 4.7 以前のバージョンを対象とするアプリケーションでは、この値の既定値は true です。

TLS プロトコルの詳細については、「Mitigation:TLS Protocols (軽減策: TLS プロトコル)」をご覧ください。 AppContext スイッチについて詳しくは、「<AppContextSwitchOverrides> Element」をご覧ください。

Windows レジストリでセキュリティを構成する

警告

レジストリ キーを設定すると、システム上のすべてのアプリケーションに影響します。 この方法は、マシンを完全に制御していて、レジストリの変更を制御できる場合にのみ使用します。

AppContext スイッチの一方または両方を設定できない場合は、このセクションで説明する Windows レジストリ キーにより、アプリが使うセキュリティ プロトコルを制御することができます。 .NET Framework 3.5 でアプリを実行している場合、または構成ファイルを編集できない場合は、一方または両方の AppContext スイッチを使用できないことがあります。 レジストリでセキュリティを構成する場合は、コードでセキュリティ プロトコルの値を指定しないでください。指定すると、レジストリ設定はオーバーライドされます。

レジストリ キーの名前は対応する AppContext スイッチの名前に似ていますが、名前の前に DontEnable が付いていません。 たとえば、AppContext スイッチ DontEnableSchUseStrongCrypto に対応するレジストリ キーの名前は SchUseStrongCrypto です。

これらのキーは、すべての .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 Version 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.2TLS 1.3 のセットで任意のサブキーを作成できます。 これらの各サブキーの下に、サブキー ClientServer の一方または両方を作成できます。 Client および Server の下には、DWORD 値 DisabledByDefault (0 または 1) および Enabled (0 または 1) を作成できます。

詳細については、TLS レジストリ設定 - Schannel に関するページをご覧ください

SCH_USE_STRONG_CRYPTO フラグ

有効になっている場合 (AppContext スイッチまたは Windows Registry では既定)、.NET Framework が SCH_USE_STRONG_CRYPTO フラグを使用すると、アプリはサーバーへの TLS 接続を開始します。 .NET Framework では、Schannel にフラグを渡して、既知の脆弱な暗号アルゴリズム、暗号スイート、および相互運用性向上のために他で有効になっている可能性のある TLS/SSL プロトコルのバージョンを無効にするよう指示します。 詳細については次を参照してください:

SCH_USE_STRONG_CRYPTO フラグは、ユーザーが SecurityProtocolType または SslProtocolsTls11、または Tls12 列挙値を明示的に使ったときも、クライアント (送信) 接続用に Schannel に渡されます。 この SCH_USE_STRONG_CRYPTO フラグが使用されるのは、アプリケーションがクライアントの役割を果たす接続のみです。 アプリケーションがサーバーの役割を果たすときには、コンピューター全体の Schannel レジストリ設定を構成することで、脆弱なプロトコルとアルゴリズムを無効にすることができます。