共用方式為


ASP.NET Core 中的資料保護金鑰管理和存留期

作者:Rick Anderson

金鑰管理

應用程式會嘗試偵測其操作環境,並自行處理金鑰組態。

  1. 如果將應用程式安裝在託管的 Azure 應用程式中,金鑰就會留存至以下 %HOME%\ASP.NET\DataProtection-Keys 資料夾中。 此資料夾使用網路儲存體進行保存,並會在裝載應用程式的所有電腦上同步。

    • 金鑰屆時將不受保護 rest。
    • DataProtection-Keys 資料夾對單一部署位置中應用程式的所有執行個體皆提供金鑰環。
    • 各部署位置,例如預備和生產位置,不會共用金鑰環。 當您在部署位置之間交換時,例如將暫存交換到生產或使用 A/B 測試,任何使用資料保護的應用程式將無法使用前一個位置內的金鑰環解密儲存的資料。 這會導致使用者登出使用標準 ASP.NET Core cookie 驗證的應用程式,原因在於它會使用資料保護來保護 Cookie。 如果您想要與位置無關的金鑰環,請使用外部金鑰環提供者,例如Azure Blob 儲存體、Azure Key Vault、SQL 存放區或 Redis 快取。
  2. 如果使用者設定檔可用,金鑰會保存至 %LOCALAPPDATA%\ASP.NET\DataProtection-Keys 資料夾。 如果作業系統是 Windows,就會使用在 rest 完成加密的 DPAPI 待用金鑰。

    應用程式集區的 setProfileEnvironment 屬性也必須啟用。 setProfileEnvironment 的預設值為 true。 在某些情況下 (例如 Windows OS),setProfileEnvironment 會設為 false。 如果金鑰並未如預期地儲存在使用者設定檔目錄中:

    1. 瀏覽至 %windir%/system32/inetsrv/config 資料夾。
    2. 開啟 applicationHost.config 檔案。
    3. 找到 <system.applicationHost><applicationPools><applicationPoolDefaults><processModel> 項目。
    4. 確認 setProfileEnvironment 屬性不存在 (其預設值為 true),或明確地將屬性值設為 true
  3. 如果應用程式裝載於 IIS 中,金鑰會保存在特殊登錄機碼中的 HKLM 登錄中,而此登錄機碼僅適用於背景工作處理序帳戶。 在 rest 期間使用 DPAPI 加密金鑰。

  4. 如果這些條件都不符合,則金鑰不會保存在目前處理序之外。 當處理序關閉時,所有產生的金鑰都會遺失。

開發人員一律完全控制,而且可以覆寫金鑰儲存方式和位置。 上述前三個選項應該為大部分的應用程式提供良好的預設值,類似過去 ASP.NET <machineKey> 自動產生常式的運作方式。 最後,後援選項是唯一需要開發人員在想要金鑰持續性時預先指定設定的案例,但此後援只會在罕見的情況下發生。

在 Docker 容器中裝載時,金鑰應該保存在 Docker 磁碟區的資料夾 (共用磁碟區或超過容器存留期的主機掛接磁碟區) 或外部提供者中,例如 Azure Key VaultRedis。 如果應用程式無法存取共用網路磁碟區,外部提供者在 Web 伺服器陣列案例中也很實用 (如需詳細資訊,請參閱 PersistKeysToFileSystem)。

警告

如果開發人員覆寫上述規則,並將資料保護系統指向特定金鑰存放庫,則會在 rest 時停用金鑰自動加密。 您可以在rest 時,透過 設定重新啟用保護。

金鑰存留期

金鑰預設會有 90 天的存留期。 金鑰到期時,應用程式會自動產生新的金鑰,並將新金鑰設定為作用中金鑰。 只要已淘汰的金鑰保留在系統上,您的應用程式就可以解密受到保護的任何資料。 如需詳細資訊,請參閱金鑰管理

預設演算法

使用的預設承載保護演算法,是用於機密性的 AES-256-CBC 和用於真實性的 HMACSHA256。 512 位元主要金鑰每 90 天會變更一次,用於在每個承載的基礎上衍生用於這些演算法的兩個子金鑰。 如需詳細資訊,請參閱子機碼衍生

刪除鍵

刪除索引鍵就永久無法存取受保護的資料。 若要降低風險,建議您不要刪除金鑰。 生成的索引鍵累積數目通常沒什麼影響力,原因是索引鍵數目不大。 如遇到特殊情況,例如:長時間執行服務,就可以刪除金鑰。 只會刪除金鑰:

  • 那個已經過時(已經無法再使用)。
  • 只有當您可接受以資料遺失風險換取節省儲存空間時,才能刪除金鑰。

我們建議您不應刪除資料保護金鑰。

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 應用程式中,金鑰就會留存至以下 %HOME%\ASP.NET\DataProtection-Keys 資料夾中。 此資料夾使用網路儲存體進行保存,並會在裝載應用程式的所有電腦上同步。

    • 金鑰屆時將不受保護 rest。
    • DataProtection-Keys 資料夾對單一部署位置中應用程式的所有執行個體皆提供金鑰環。
    • 各部署位置,例如預備和生產位置,不會共用金鑰環。 當您在部署位置之間交換時,例如將暫存交換到生產或使用 A/B 測試,任何使用資料保護的應用程式將無法使用前一個位置內的金鑰環解密儲存的資料。 這會導致使用者登出使用標準 ASP.NET Core cookie 驗證的應用程式,原因在於它會使用資料保護來保護 Cookie。 如果您想要與位置無關的金鑰環,請使用外部金鑰環提供者,例如Azure Blob 儲存體、Azure Key Vault、SQL 存放區或 Redis 快取。
  2. 如果使用者設定檔可用,金鑰會保存至 %LOCALAPPDATA%\ASP.NET\DataProtection-Keys 資料夾。 如果作業系統是 Windows,就會使用在 rest 完成加密的 DPAPI 待用金鑰。

    應用程式集區的 setProfileEnvironment 屬性也必須啟用。 setProfileEnvironment 的預設值為 true。 在某些情況下 (例如 Windows OS),setProfileEnvironment 會設為 false。 如果金鑰並未如預期地儲存在使用者設定檔目錄中:

    1. 瀏覽至 %windir%/system32/inetsrv/config 資料夾。
    2. 開啟 applicationHost.config 檔案。
    3. 找到 <system.applicationHost><applicationPools><applicationPoolDefaults><processModel> 項目。
    4. 確認 setProfileEnvironment 屬性不存在 (其預設值為 true),或明確地將屬性值設為 true
  3. 如果應用程式裝載於 IIS 中,金鑰會保存在特殊登錄機碼中的 HKLM 登錄中,而此登錄機碼僅適用於背景工作處理序帳戶。 在 rest 期間使用 DPAPI 加密金鑰。

  4. 如果這些條件都不符合,則金鑰不會保存在目前處理序之外。 當處理序關閉時,所有產生的金鑰都會遺失。

開發人員一律完全控制,而且可以覆寫金鑰儲存方式和位置。 上述前三個選項應該為大部分的應用程式提供良好的預設值,類似過去 ASP.NET <machineKey> 自動產生常式的運作方式。 最後,後援選項是唯一需要開發人員在想要金鑰持續性時預先指定設定的案例,但此後援只會在罕見的情況下發生。

在 Docker 容器中裝載時,金鑰應該保存在 Docker 磁碟區的資料夾 (共用磁碟區或超過容器存留期的主機掛接磁碟區) 或外部提供者中,例如 Azure Key VaultRedis。 如果應用程式無法存取共用網路磁碟區,外部提供者在 Web 伺服器陣列案例中也很實用 (如需詳細資訊,請參閱 PersistKeysToFileSystem)。

警告

如果開發人員覆寫上述規則,並將資料保護系統指向特定金鑰存放庫,則會在 rest 時停用金鑰自動加密。 您可以在rest 時,透過 設定重新啟用保護。

金鑰存留期

金鑰預設會有 90 天的存留期。 金鑰到期時,應用程式會自動產生新的金鑰,並將新金鑰設定為作用中金鑰。 只要已淘汰的金鑰保留在系統上,您的應用程式就可以解密受到保護的任何資料。 如需詳細資訊,請參閱金鑰管理

預設演算法

使用的預設承載保護演算法,是用於機密性的 AES-256-CBC 和用於真實性的 HMACSHA256。 512 位元主要金鑰每 90 天會變更一次,用於在每個承載的基礎上衍生用於這些演算法的兩個子金鑰。 如需詳細資訊,請參閱子機碼衍生

其他資源