.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 アプリケーションのセキュリティ保護に関する推奨事項を示します。
このドキュメントが役に立つ方
- System.Net API (System.Net.Http.HttpClient や System.Net.Security.SslStream など) を直接使用する。
- System.ServiceModel 名前空を使って WCF クライアントおよびサービスを直接使用する。
.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.DisableUsingServicePointManagerSecurityProtocols
が true
に設定されていると、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
に設定すると、アプリは強力な暗号を使うようになります。 DontEnableSchUseStrongCrypto
を false
にすると、安全性の高いネットワーク プロトコル (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.2
、TLS 1.3
のセットで任意のサブキーを作成できます。 これらの各サブキーの下に、サブキー Client
と Server
の一方または両方を作成できます。 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 または SslProtocols の Tls11
、または Tls12
列挙値を明示的に使ったときも、クライアント (送信) 接続用に Schannel
に渡されます。 この SCH_USE_STRONG_CRYPTO
フラグが使用されるのは、アプリケーションがクライアントの役割を果たす接続のみです。 アプリケーションがサーバーの役割を果たすときには、コンピューター全体の Schannel
レジストリ設定を構成することで、脆弱なプロトコルとアルゴリズムを無効にすることができます。
.NET