【问题标题】:Using Azure Key Vault for storing username and password使用 Azure Key Vault 存储用户名和密码
【发布时间】:2017-03-01 21:39:32
【问题描述】:

我正在开发一个应用程序,我想在其中存储将由守护程序服务使用的服务帐户的用户名和密码。

这个想法是为应用程序管理员提供一个仪表板,他/她可以在其中输入服务帐户的凭据,然后可以将其存储在安全的地方。

我可以考虑将其存储在 Azure Vault 之类的安全地方,并在需要时从那里获取。但是,密钥和机密是 Azure Vault 中的不同实体。我不能将它们作为组合存储在某个地方。

以前有人这样做过吗?或者有没有更好的替代方法来在 Azure 中存储凭据?

【问题讨论】:

  • 只是好奇,你说的service account是代表他们管理用户的Azure订阅吗?
  • 不,@GauravMantri。这些将是 Dynamics CRM 服务帐户的凭据。该帐户将用于通过守护程序应用更新 Dynamics CRM 中的实体。顺便说一句,在博客和文章方面做得很好,我确实关注你的博客 ;-)
  • 服务帐号的用户名和密码会由管理员输入,那么再次添加到 azure key vault 有什么价值?
  • @HaithamShaddad 我想将它安全地存储在某个地方。显然不在 sql 表中:-)\
  • Azure 密钥保管库旨在保存将在应用程序中使用的机密,在 Windows、IIS 中,服务帐户是在应用程序池级别配置的,之后您再也不需要其密码。

标签: azure azure-keyvault


【解决方案1】:

您可以使用 Azure blob 存储用于加密静态数据的技术(信封方法): https://docs.microsoft.com/en-us/azure/storage/storage-client-side-encryption

KeyVault 能够打包/解包(加密/解密)对称密钥,因此您可以安全地将它们与加密数据一起存储。

以下是一般步骤:

  1. 使用 RNGCryptoServiceProvider 生成 AES 密钥(256 位,CBC 模式)
  2. 加密数据(凭据)
  3. 保存初始化向量 (IV)。您可以将其连接到密文字节数组以便稍后在您想要解密时检索 - IV 不需要保护。
  4. 使用 KeyVault 中的密钥包装(加密)生成的 AES 对称密钥。
  5. 存储包装的 AES 密钥、IV、密文和密钥版本(GUID 位于 KeyVault 中 URI 的末尾)。
  6. 确保将 KeyVault 中的 Wrap / Unwrap 权限授予在 Azure AD 中创建的应用程序注册。在 GetToken() 中使用客户端 ID/应用程序 ID + 密钥或 pfx 对 Azure 进行身份验证。

您将需要这些 nuget 包:

Install-Package Microsoft.Azure.KeyVault
Install-Package Microsoft.Azure.KeyVault.Extensions
Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory -Version 2.16.204221202

获取 KeyVaultKeyResolver 的引用

KeyVaultKeyResolver cloudResolver = new KeyVaultKeyResolver(Utils.GetToken);

// Example GetToken implementation
public class Utils {
    // Retrive JWT token to be used for KeyVault access.
    internal async static Task<string> GetToken(string authority, string resource, string scope)
    {
        var authContext = new AuthenticationContext(authority);
        // Could use pfx instead
        ClientCredential clientCred = new ClientCredential(
            ConfigurationManager.AppSettings["clientId"],
            ConfigurationManager.AppSettings["clientSecret"]);

        AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred);

        if (result == null)
            throw new InvalidOperationException("Failed to obtain the JWT token.");

        return result.AccessToken;
    }
}

拥有 KeyResolver 后,您可以获得一个 IKey 来包装/解包您的 AES 对称密钥,如下所示...

包装/加密 AES 密钥

keyID 是来自 Key Vault 的 URI,aesKey 是要加密的 AES 密钥的字节[]:

// Resolve an IKey by Key ID from URI in KeyVault
var keyEncryptionKey = cloudResolver.ResolveKeyAsync(keyId, CancellationToken.None).GetAwaiter().GetResult();

// Take our gen'ed AES Key and wrap (encrypt) it.
Tuple<byte[], string> wrappedKey = keyEncryptionKey.WrapKeyAsync(aeskey, null /* algorithm */, CancellationToken.None).GetAwaiter().GetResult();

元组中的 byte[] 包含对称密钥的加密字节和使用的算法的名称。将这些作为元数据与您的密文一起保存。

解包/解密 AES 密钥

使用相同的密钥调用(密钥版本很重要),algoName 是用于包装密钥的算法的名称(例如“RSA-OAEP”)。

// Retrieve the IKey by Key ID
// Unwrap Key
byte[] aesKey = rsa.UnwrapKeyAsync(wrappedKeyBytes, algoName, CancellationToken.None).GetAwaiter().GetResult();

其他需要考虑的细节是密钥备份/恢复和密钥轮换。

【讨论】:

    猜你喜欢
    • 2017-09-12
    • 2019-12-24
    • 2021-01-26
    • 2022-01-27
    • 1970-01-01
    • 2019-07-28
    • 2021-01-11
    • 1970-01-01
    • 2017-01-19
    相关资源
    最近更新 更多