多个 Pod 的数据保护密钥轮换策略是什么?

2024-03-17

I used services.AddDataProtection().PersistKeysToFileSystem(path).ProtectKeysWithAzureKeyVault(authData).加密数据保护密钥。部署后 24 小时内未生成新的数据保护密钥。这意味着,在当前数据保护密钥过期之前,不会进行任何加密。

现在,为了强制生成数据保护密钥,我可以删除最新的数据保护密钥并重新启动 Pod,但这将导致此处描述的竞争条件:https://github.com/dotnet/aspnetcore/issues/28475 https://github.com/dotnet/aspnetcore/issues/28475所以我需要重新启动它们。使用现已删除的数据保护密钥加密 cookie 的用户是否会被注销?

这也让我感到困扰,因为如果数据保护密钥每 180 天轮换一次,到底会发生什么?用户的 cookie 使用它进行加密,因此如果他们登录,他们的 cookie 会不再有效吗? 此外,如果 6 个 Pod 之一生成新的数据保护密钥,其余 Pod 何时同步?您是否有可能使用 1 个 pod 获取表单,然后使用另一个 pod 提交表单,同时它们使用不同的数据保护密钥?

该如何应对这一切呢?


这个问题仍然悬而未决,有一个元问题链接到有关该主题的其他悬而未决的问题。

https://github.com/dotnet/aspnetcore/issues/36157 https://github.com/dotnet/aspnetcore/issues/36157

我遇到了同样的问题,但我没有使用 Pod,而是使用 AWS Lambda 函数。

我通过禁用自动密钥生成解决了该问题:

    services.AddDataProtection()
        .DisableAutomaticKeyGeneration()

并亲自管理钥匙。我至少有两把钥匙:

  • 默认键。激活后 190 天到期。它是 180 天内的默认密钥。
  • 下一个关键。它会在当前密钥到期前 10 天激活。激活后 190 天到期。它将成为 180 天内的默认密钥。

这是我在部署 lambda 函数之前执行的代码,然后每月执行一次:

public class KeyringUpdater
{
    private readonly ILogger<KeyringUpdater> logger;
    private readonly IKeyManager keyManager;

    public KeyringUpdater(IKeyManager keyManager, ILogger<KeyringUpdater> logger)
    {
        this.logger = logger;
        this.keyManager = keyManager;
    }

    private IKey? GetDefaultKey(IReadOnlyCollection<IKey> keys)
    {
        var now = DateTimeOffset.UtcNow;
        return keys.FirstOrDefault(x => x.ActivationDate <= now && x.ExpirationDate > now && x.IsRevoked == false);
    }

    private IKey? GetNextKey(IReadOnlyCollection<IKey> keys, IKey key)
    {
        return keys.FirstOrDefault(x => x.ActivationDate > key.ActivationDate && x.ActivationDate < key.ExpirationDate && x.ExpirationDate > key.ExpirationDate && x.IsRevoked == false);
    }

    public void Update()
    {
        var keys = this.keyManager.GetAllKeys();
        logger.LogInformation("Found {Count} keys", keys.Count);
        var defaultKey = GetDefaultKey(keys);
        if (defaultKey == null)
        {
            logger.LogInformation("No default key found");
            var now = DateTimeOffset.UtcNow;
            defaultKey = this.keyManager.CreateNewKey(now, now.AddDays(190));
            logger.LogInformation("Default key created. ActivationDate: {ActivationDate}, ExpirationDate: {ExpirationDate}", defaultKey.ActivationDate, defaultKey.ExpirationDate);
            keys = this.keyManager.GetAllKeys();
        }
        else
        {
            logger.LogInformation("Found default key. ActivationDate: {ActivationDate}, ExpirationDate: {ExpirationDate}", defaultKey.ActivationDate, defaultKey.ExpirationDate);
        }
        var nextKey = GetNextKey(keys, defaultKey);
        if (nextKey == null)
        {
            logger.LogInformation("No next key found");
            nextKey = this.keyManager.CreateNewKey(defaultKey.ExpirationDate.AddDays(-10), defaultKey.ExpirationDate.AddDays(180));
            logger.LogInformation("Next key created. ActivationDate: {ActivationDate}, ExpirationDate: {ExpirationDate}", nextKey.ActivationDate, nextKey.ExpirationDate);
        }
        else
        {
            logger.LogInformation("Found next key. ActivationDate: {ActivationDate}, ExpirationDate: {ExpirationDate}", nextKey.ActivationDate, nextKey.ExpirationDate);
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多个 Pod 的数据保护密钥轮换策略是什么? 的相关文章

随机推荐