ASP.NET Core でのデータ保護のキー管理と有効期間

作成者: Rick Anderson

キーの管理

アプリにより、その運用環境の検出とキー構成の処理が独自に試行されます。

  1. アプリが Azure Apps でホストされている場合、キーは %HOME%\ASP.NET\DataProtection-Keys フォルダーに保持されます。 このフォルダーはネットワーク ストレージにバックアップされ、アプリをホストしているすべてのマシンで同期されています。

    • restのキーは保護されていません。
    • DataProtection-Keys フォルダーから、単一のデプロイ スロットのアプリのすべてのインスタンスにキー リングが提供されます。
    • ステージングや運用などの別のデプロイ スロットでは、キー リングが共有されません。 ステージングから運用へのスワップや A/B テストの使用など、デプロイ スロットをスワップすると、データ保護を使っているアプリからは、前のスロット内のキー リングを使って格納されたデータを復号化できなくなります。 その結果、標準の ASP.NET Core cookie 認証を使うアプリでは、データ保護を使って cookie が保護されているため、ユーザーがログアウトされます。 スロットに依存しないキー リングが必要な場合は、Azure Blob Storage、Azure Key Vault、SQL ストア、Redis キャッシュなどの外部キー リング プロバイダーを使います。
  2. ユーザー プロファイルを使用できる場合、キーは %LOCALAPPDATA%ASP.NET\DataProtection-Keys フォルダーに保持されます。 オペレーティング システムが Windows の場合、キーはrestに DPAPI を使って暗号化されます。

    アプリ プールの setProfileEnvironment 属性も有効にする必要があります。 setProfileEnvironment の既定値は trueです。 一部のシナリオ (たとえば、Windows OS) では、setProfileEnvironmentfalse に設定されます。 キーが期待どおりにユーザー プロファイル ディレクトリに格納されていない場合:

    1. %windir%/system32/inetsrv/config フォルダーに移動します。
    2. applicationHost.config ファイルを開きます。
    3. <system.applicationHost><applicationPools><applicationPoolDefaults><processModel> 要素を探します。
    4. setProfileEnvironment 属性 (その規定値は true です) が存在しないことを確認するか、属性の値を明示的に true に設定します。
  3. アプリが IIS でホストされている場合、HKLM レジストリ内の、ワーカー プロセス アカウントにのみ ACL が設定されている特別なレジストリ キーにキーが保持されます。 キーは DPAPI を使用してrestに暗号化されます。

  4. これらの条件のいずれにも該当しない場合、キーは現在のプロセスの外部には保持されません。 プロセスがシャットダウンすると、生成されたキーはすべて失われます。

開発者は常にフル コントロール状態であり、キーの格納方法と場所をオーバーライドすることができます。 上記の最初の 3 つのオプションは、これまでの ASP.NET <machineKey> の自動生成ルーチンのしくみと同様に、ほとんどのアプリに適した既定として利用できます。 最後のフォールバック オプションは、開発者がキーの保持が必要な場合に事前に構成を指定する必要がある唯一のシナリオですが、まれな状況でのみ、このフォールバックが発生します。

Docker コンテナーでホストする場合、キーは Docker ボリューム (共有ボリュームまたはコンテナーの有効期間を超えて保持されるホスト マウント ボリューム) のフォルダーか、Azure Key VaultRedis などの外部プロバイダーに保持する必要があります。 外部プロバイダーは、アプリから共有ネットワーク ボリュームにアクセスできない場合の Web ファームのシナリオでも役に立ちます (詳細については、PersistKeysToFileSystem に関するページを参照してください)。

警告

開発者が上記の規則をオーバーライドして、特定のキー リポジトリのデータ保護システムを指した場合、restのキーの自動暗号化は無効になります。 restの保護は構成によって再度有効にすることができます。

キーの有効期間

キーの有効期間は既定で 90 日です。 キーの有効期限が切れると、アプリによって自動的に新しいキーが生成され、その新しいキーがアクティブ キーとして設定されます。 廃止されたキーがシステムに残っている限り、そのキーで保護されたデータをアプリから復号化できます。 詳細については、キー管理に関するページを参照してください。

既定のアルゴリズム

既定で使われるペイロード保護アルゴリズムは、機密性には AES-256-CBC、信頼性には HMACSHA256 です。 90 日ごとに変更される 512 ビットのマスター キーは、ペイロードごとにこれらのアルゴリズムに使われる 2 つのサブキーを派生させるために使われます。 詳細については、サブキーの派生に関するページを参照してください。

キーを削除する。

キーを削除すると、保護されたデータに永続的にアクセスできなくなります。 そのリスクを軽減するために、キーを削除しないことをお勧めします。 結果として得られるキーの蓄積は、サイズが小さいため、通常は影響が最小限に抑えられます。 非常に実行時間の長いサービスなど、例外的な場合は、キーを削除できます。 キーの削除のみ:

  • 古い(もう使用されていない)もの。
  • ストレージの節約と引き換えに、データ損失のリスクを受け入れることができる場合にのみ、キーを削除します。

データ保護キーは削除しないことをお勧めします。

using Microsoft.AspNetCore.DataProtection.KeyManagement;

var services = new ServiceCollection();
services.AddDataProtection();

var serviceProvider = services.BuildServiceProvider();

var keyManager = serviceProvider.GetService<IKeyManager>();

if (keyManager is IDeletableKeyManager deletableKeyManager)
{
    var utcNow = DateTimeOffset.UtcNow;
    var yearAgo = utcNow.AddYears(-1);

    if (!deletableKeyManager.DeleteKeys(key => key.ExpirationDate < yearAgo))
    {
        Console.WriteLine("Failed to delete keys.");
    }
    else
    {
        Console.WriteLine("Old keys deleted successfully.");
    }
}
else
{
    Console.WriteLine("Key manager does not support deletion.");
}

その他のリソース

キーの管理

アプリにより、その運用環境の検出とキー構成の処理が独自に試行されます。

  1. アプリが Azure Apps でホストされている場合、キーは %HOME%\ASP.NET\DataProtection-Keys フォルダーに保持されます。 このフォルダーはネットワーク ストレージにバックアップされ、アプリをホストしているすべてのマシンで同期されています。

    • restのキーは保護されていません。
    • DataProtection-Keys フォルダーから、単一のデプロイ スロットのアプリのすべてのインスタンスにキー リングが提供されます。
    • ステージングや運用などの別のデプロイ スロットでは、キー リングが共有されません。 ステージングから運用へのスワップや A/B テストの使用など、デプロイ スロットをスワップすると、データ保護を使っているアプリからは、前のスロット内のキー リングを使って格納されたデータを復号化できなくなります。 その結果、標準の ASP.NET Core cookie 認証を使うアプリでは、データ保護を使って cookie が保護されているため、ユーザーがログアウトされます。 スロットに依存しないキー リングが必要な場合は、Azure Blob Storage、Azure Key Vault、SQL ストア、Redis キャッシュなどの外部キー リング プロバイダーを使います。
  2. ユーザー プロファイルを使用できる場合、キーは %LOCALAPPDATA%ASP.NET\DataProtection-Keys フォルダーに保持されます。 オペレーティング システムが Windows の場合、キーはrestに DPAPI を使って暗号化されます。

    アプリ プールの setProfileEnvironment 属性も有効にする必要があります。 setProfileEnvironment の既定値は trueです。 一部のシナリオ (たとえば、Windows OS) では、setProfileEnvironmentfalse に設定されます。 キーが期待どおりにユーザー プロファイル ディレクトリに格納されていない場合:

    1. %windir%/system32/inetsrv/config フォルダーに移動します。
    2. applicationHost.config ファイルを開きます。
    3. <system.applicationHost><applicationPools><applicationPoolDefaults><processModel> 要素を探します。
    4. setProfileEnvironment 属性 (その規定値は true です) が存在しないことを確認するか、属性の値を明示的に true に設定します。
  3. アプリが IIS でホストされている場合、HKLM レジストリ内の、ワーカー プロセス アカウントにのみ ACL が設定されている特別なレジストリ キーにキーが保持されます。 キーは DPAPI を使用してrestに暗号化されます。

  4. これらの条件のいずれにも該当しない場合、キーは現在のプロセスの外部には保持されません。 プロセスがシャットダウンすると、生成されたキーはすべて失われます。

開発者は常にフル コントロール状態であり、キーの格納方法と場所をオーバーライドすることができます。 上記の最初の 3 つのオプションは、これまでの ASP.NET <machineKey> の自動生成ルーチンのしくみと同様に、ほとんどのアプリに適した既定として利用できます。 最後のフォールバック オプションは、開発者がキーの保持が必要な場合に事前に構成を指定する必要がある唯一のシナリオですが、まれな状況でのみ、このフォールバックが発生します。

Docker コンテナーでホストする場合、キーは Docker ボリューム (共有ボリュームまたはコンテナーの有効期間を超えて保持されるホスト マウント ボリューム) のフォルダーか、Azure Key VaultRedis などの外部プロバイダーに保持する必要があります。 外部プロバイダーは、アプリから共有ネットワーク ボリュームにアクセスできない場合の Web ファームのシナリオでも役に立ちます (詳細については、PersistKeysToFileSystem に関するページを参照してください)。

警告

開発者が上記の規則をオーバーライドして、特定のキー リポジトリのデータ保護システムを指した場合、restのキーの自動暗号化は無効になります。 restの保護は構成によって再度有効にすることができます。

キーの有効期間

キーの有効期間は既定で 90 日です。 キーの有効期限が切れると、アプリによって自動的に新しいキーが生成され、その新しいキーがアクティブ キーとして設定されます。 廃止されたキーがシステムに残っている限り、そのキーで保護されたデータをアプリから復号化できます。 詳細については、キー管理に関するページを参照してください。

既定のアルゴリズム

既定で使われるペイロード保護アルゴリズムは、機密性には AES-256-CBC、信頼性には HMACSHA256 です。 90 日ごとに変更される 512 ビットのマスター キーは、ペイロードごとにこれらのアルゴリズムに使われる 2 つのサブキーを派生させるために使われます。 詳細については、サブキーの派生に関するページを参照してください。

その他の技術情報