我必须在我的应用程序中实现密钥轮换。我有一些想法如何做到这一点,但我不确定该解决方案是否一切正常。
好的,让我们开始吧。我的应用程序中有几个地方使用KeyVaultClient(Azure KeyVault Client)进行解密。它的工作很好。在我的应用程序中,有一些地方使用KeyVaultClient进行加密。目前(仍在开发阶段),我正在使用硬编码的参数(vaultBaseUrl,keyName,keyVersion)。但我想更进一步,将此参数移动到 app.config 文件。
在这里,问题开始了如何处理keyVersion变量(其余的我认为我可以轻松地存储在app.config文件中,不是吗?我有几个想法:
对于加密:
- 我可以将当前的keyVersion存储在app.config中,并在每次加密数据时使用此值。
- 我可以从KeyVaultClients读取所有密钥(GetKeysAsync),然后按活动标志过滤它们并按到期日期排序。最后使用最新的。
对于解密:
- 我可以将用于加密的密钥版本存储在加密数据中(我正在转换为 Base64String 的加密结果)。我的意思是我可以在字符串结果中添加 32 个字符(keyVersion)前缀。
- 没有更多的想法,也许使用 app.config 中的 keyVersion,但它会产生密钥轮换问题。
也许有一些工具/库可以为我处理所有这些工作? :p
目前,新密钥由管理员手动插入。在下一阶段,我将为此实现计划任务。
也许有一些工具/库可以为我处理这一切?
正如您提到的,您需要加密密钥版本与解密密钥版本一致。最好是可以共享您的方案。以加密 blob 为例。如果 blob 已加密,它将具有包含 keyId 的元数据 ["加密数据"]。在您的情况下,也许您还可以为对象添加一个带有 keyId 的属性。当您尝试解密时,您可以从对象中获取 keyId。
目前,新密钥由管理员手动插入。在下一阶段,我将为此实现计划任务。
如果要创建密钥,可以在 Web 作业或 Azure 函数中按照此代码示例执行此操作。
static string _clientId= "xxxxxxxxxxxxx";
static string _clientSecret = "xxxxxxxxxxxxxxxx";
static string _tenantId = "xxxxxxxxxxxxxxxx";
public static async Task<string> GetAccessToken(string azureTenantId, string azureAppId, string azureSecretKey)
{
var context = new AuthenticationContext("https://login.windows.net/" + _tenantId);
ClientCredential clientCredential = new ClientCredential(_clientId, _clientSecret);
var tokenResponse = await context.AcquireTokenAsync("https://vault.azure.net", clientCredential);
var accessToken = tokenResponse.AccessToken;
return accessToken;
}
var kv = new KeyVaultClient(GetAccessToken);
var result = kv.CreateKeyAsync(vault,keyName,keyType).Result;