未配置 XML 加密器 - 使用 Key Vault 时

kir*_*tha 5 linux data-protection azure docker azure-keyvault

我有一个 netcoreapp2.2 容器化应用程序,它使用 azure key Vault 来存储密钥,还使用:

app.UseAuthentication(); 
Run Code Online (Sandbox Code Playgroud)

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
Run Code Online (Sandbox Code Playgroud)

我正在应用服务下的托管 Linux 环境中构建/运行 docker 映像。我正在使用 azure 容器注册表和开发操作管道来维护我的应用程序。Azure 控制部署过程和“docker run”命令。

我的应用程序运行良好,但是在容器日志中我看到:

2019-12-13T17:18:12.207394900Z [40m[1m[33mwarn[39m[22m[49m: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
2019-12-13T17:18:12.207436700Z       No XML encryptor configured. Key {...} may be persisted to storage in unencrypted form.
...
2019-12-13T17:18:14.540484659Z Application started. Press Ctrl+C to shut down.
Run Code Online (Sandbox Code Playgroud)

我意识到有很多其他帖子都提到使用其他存储机制,但是我正在使用密钥保管库来存储我的敏感数据。JWT 全部由 Key Vault 处理。我有一些控制 DEV/QA/PROD 静态变量的应用程序设置,但它们根本不是敏感数据。

我也不确定内存中存储了什么密钥,因为我所有的敏感密钥都完全在应用程序之外,并由以下方式调用:

var azureServiceTokenProvider = new AzureServiceTokenProvider();
                var keyVaultClient = new KeyVaultClient(
                    new KeyVaultClient.AuthenticationCallback(
                        azureServiceTokenProvider.KeyVaultTokenCallback));

                config.AddAzureKeyVault(
                    $"https://{builtConfig["MY_KEY_VAULT_ID"]}.vault.azure.net/",
                    keyVaultClient,
                    new DefaultKeyVaultSecretManager());
Run Code Online (Sandbox Code Playgroud)

我很难理解为什么会抛出此警告,以及我是否应该采取其他措施来缓解该问题。我个人没有看到副作用,并且应用程序重新启动似乎没有任何影响,因为我使用的是不记名令牌,并且令牌过期、密码重置等其他问题不适用。

所以我剩下的问题是我可以采取任何其他步骤来避免此警告吗?我是否需要确保对于 Linux 环境中可能存在的任何配置设置都有更好的静态数据机制?我可以安全地忽略这个警告吗?

kir*_*tha 5

我花了一段时间才找到一种适合我的应用程序需求的方法,但我想澄清一些对我来说没有意义的其他堆栈答案以及我最终如何理解这个问题。

太长了;由于我已经在使用 Key Vault,因此我对 .net core 的工作原理感到困惑。我没有意识到 config.AddAzureKeyVault() 与 .net core 如何决定在应用程序服务上存储静态数据无关。

当您看到此警告时:

No XML encryptor configured. Key {GUID} may be persisted to storage in unencrypted form.
Run Code Online (Sandbox Code Playgroud)

设置什么 GUID 并不重要:该数据字符串并未以静态方式加密存储。

对于我的风险分析来说,任何未静态加密的信息都是一个坏主意,因为这可能意味着在未来的任何时候,某种敏感数据可能会泄漏,然后暴露给攻击者。最后,我选择将静态数据分类为敏感数据,并谨慎对待潜在的攻击面。

我一直在努力尝试以清晰简洁的方式解释这一点,但很难用几句话来概括。这是我学到的。

  • 在这种情况下,访问控制 (IAM) 是您的朋友,因为您可以为您的应用程序声明系统分配的身份并使用基于角色的访问控制。就我而言,我使用应用程序身份通过 RBAC 控制对 Key Vault 和 Azure 存储的访问。这使得无需 SAS 令牌或访问密钥即可更轻松地进行访问。
  • Azure 存储将是您正在创建的文件的最终目的地,但它将是控制加密密钥的保管库。我在密钥保管库中创建了一个 RSA 密钥,该密钥用于加密引发原始错误的 XML 文件。
  • 我脑子里犯的错误之一是我希望两个人将加密的 XML 写入密钥保管库。然而,这并不是微软描述的真正用例。有两种机制:PersistKeysTo 和 ProtectKeysWith。当我通过我厚实的头脑明白这一点时,一切都有意义了。

我使用以下方法删除警告并创建静态加密数据:

services.AddDataProtection()
    // Create a CloudBlockBlob with AzureServiceTokenProvider
    .PersistKeysToAzureBlobStorage(...)
    // Create a KeyVaultClient with AzureServiceTokenProvider
    // And point to the RSA key by id
    .ProtectKeysWithAzureKeyVault(...);
Run Code Online (Sandbox Code Playgroud)

我已经在我的应用程序中使用了 RBAC 和 Key Vault(具有包装/解开权限),但我还将 Storage Blob Data Contributor 添加到了存储帐户。

如何创建 blob 取决于您,但一个问题是同步创建访问令牌:

    // GetStorageAccessToken()
    var token = new AzureServiceTokenProvider();
    return token.GetAccessTokenAsync("https://storage.azure.com/")
        .GetAwaiter()
        .GetResult();
Run Code Online (Sandbox Code Playgroud)

然后我从一个方法中调用它:

    var uri = new Uri($"https://{storageAccount}.blob.core.windows.net/{containerName}/{blobName}");
    //Credentials.
    var tokenCredential = new TokenCredential(GetStorageAccessToken());
    var storageCredentials = new StorageCredentials(tokenCredential);
    return new CloudBlockBlob(uri, storageCredentials);
Run Code Online (Sandbox Code Playgroud)

克服这个障碍后,加密就很简单了。Keyvault ID 是您正在使用的加密密钥的位置。

https://mykeyvaultname.vault.azure.net/keys/my-key-name/{VersionGuid}
Run Code Online (Sandbox Code Playgroud)

创建客户端是

var token = new AzureServiceTokenProvider();
var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(token.KeyVaultTokenCallback));

services.AddDataProtection()
    .ProtectKeysWithAzureKeyVault(client, keyVaultId);
Run Code Online (Sandbox Code Playgroud)

我还必须赞扬这个博客:https : //joonasw.net/view/using-azure-key-vault-and-azure-storage-for-asp-net-core-data-protection-keys我朝着正确的方向前进。

https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/default-settings?view=aspnetcore-2.2这也指出了为什么密钥没有加密

https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles - 应用程序的 RBAC

https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?view=aspnetcore-3.1起初这很令人困惑,但对于如何授予访问权限和限制有一个很好的警告生产中的访问。