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

时间:2019-12-14 01:38:10

标签: linux azure docker data-protection

我有一个netcoreapp2.2容器化应用程序,该应用程序使用azure密钥库来存储密钥,并且还使用:

app.UseAuthentication(); 

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

我正在App Services下的托管linux环境中构建/运行docker映像。我正在使用azure容器注册表和dev ops管道来维护我的应用程序。 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.

我意识到与此相关的许多其他帖子都暗示使用其他存储机制,但是我正在使用密钥库来存储我的敏感数据。 JWT全部由密钥库处理。我有一些应用程序设置可以控制DEV / QA / PROD的静态变量,但它们根本不是敏感数据。

我还不确定什么密钥存储在内存中,因为 all 我的敏感密钥完全不在应用程序外部,并且由以下人员调用:

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());

我很难理解为什么会发出此警告,以及是否应该采取其他措施来缓解此问题。我个人还没有看到副作用,并且由于我使用的是承载令牌,因此应用程序重启似乎没有任何作用,并且其他问题(例如令牌到期,密码重置等)均不适用。

因此,我要问是否还有其他步骤可以避免此警告?我是否需要确保对Linux环境中的任何配置设置都有一个更好的静态数据机制?我可以安全地忽略此警告吗?

2 个答案:

答案 0 :(得分:0)

我花了一段时间才找到适合我的应用程序需求的方法,但我想对其他一些对我来说毫无意义的堆栈答案以及我最终的理解方式提供一些清晰度问题。

TLDR;由于我已经在使用密钥保管库,因此使.net core的工作方式感到困惑。我没有意识到config.AddAzureKeyVault()与.net core如何决定将静态数据存储在应用程序服务上无关。

看到此警告时:

No XML encryptor configured. Key {GUID} may be persisted to storage in unencrypted form.

设置GUID确实无关紧要:该数据串在静态时未加密存储。

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

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

    在这种情况下,
  • 访问控制(IAM)是您的朋友,因为您可以为应用程序声明系统分配的身份并使用基于角色的访问控制。就我而言,我使用我的应用程序身份来控制对带有RBAC的密钥库和Azure存储的访问。这使得在没有SAS令牌或访问密钥的情况下访问变得更加容易。
  • Azure存储将是所创建文件的最终目标,但它将是控制加密密钥的保管库。我在密钥库中创建了一个RSA密钥,该密钥是对引发原始错误的XML文件进行加密的过程。
  • 我脑子里犯的一个错误是我想要两个人将加密的XML写入密钥库。但是,这并不是Microsoft描述的用例。有两种机制:PersistKeysTo和ProtectKeysWith。我一头厚脑袋就明白了,一切都说得通。

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

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

我已经将RBAC用于具有密钥保管库(具有包装/展开权限)的RBAC,但是我还向存储帐户添加了Storage Blob Data Contributor。

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

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

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

    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);

克服此障碍后,立即进行加密。 Keyvault ID是您正在使用的加密密钥的位置。

https://mykeyvaultname.vault.azure.net/keys/my-key-name/{VersionGuid}

创建客户端是

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

services.AddDataProtection()
    .ProtectKeysWithAzureKeyVault(client, keyVaultId);

我还必须赞扬这个博客:https://joonasw.net/view/using-azure-key-vault-and-azure-storage-for-asp-net-core-data-protection-keys,因为这为我指明了正确的方向。

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

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

https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?view=aspnetcore-3.1乍一看让人感到困惑,但是对于如何授予访问权限和限制生产中的访问权限发出了很好的警告。

答案 1 :(得分:0)

也许您必须配置数据保护策略以使用CryptographicAlogrithms,如下所示:

 .UseCryptographicAlgorithms(new AuthenticatedEncryptorConfiguration()
                {
                    EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
                    ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
                });

此外,以下是一些有关数据保护政策的警告

ASP.Net核心DataProtection将密钥存储在HOME目录(/root/.aspnet/DataProtection-Keys)中,因此,当容器重新启动密钥丢失时,这可能会使服务崩溃。

这可以通过按住键来解决

  • 在持久位置(卷)上持久键并安装该卷 到Docker容器
  • 在外部密钥存储区(例如Azure或Redis)中坚持使用密钥

有关ASP.NET DataProtection的更多详细信息:

https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?view=aspnetcore-3.1

https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/introduction?view=aspnetcore-3.1

使用以下命令将外部卷(C:/ temp-kyes)安装到Docker容器卷(/root/.aspnet/DataProtection-Keys)

docker run -d -v /c/temp-keys:/root/.aspnet/DataProtection-Keys container-name

此外,您需要更新Starup.cs-ConfigureServices以配置DataProtection策略

services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(@"C:\temp-keys\"))
                .UseCryptographicAlgorithms(new AuthenticatedEncryptorConfiguration()
                {
                    EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
                    ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
                });