不使用 KeyVault 的 Azure 表存储客户端加密

Posted

技术标签:

【中文标题】不使用 KeyVault 的 Azure 表存储客户端加密【英文标题】:Azure Table Storage Client Side Encryption WITHOUT Using KeyVault 【发布时间】:2015-11-12 22:14:53 【问题描述】:

我有一些敏感信息要加密并存储在 Azure 表存储中。老实说,从一种幼稚的方法来看,对所有值使用相同的 AES 密钥可能就足够了,因为我几乎不可能有足够的数据加密,以便有人进行任何有意义的密码分析。但是,我知道最好的做法是限制使用相同的对称密钥。

最近,微软通过 Azure KeyVault 发布了 Azure 表存储的客户端加密。它允许您生成 RSA 密钥并将其存储在 KeyVault 中,客户端库将为表存储中的每一行生成一个新的对称密钥,并使用您的 RSA 密钥加密对称密钥。这是完美的,因为没有办法对密文进行差分密码分析,因为它们都使用不同的密钥。这特别好,因为他们的库完成了所有的工作,您所要做的就是从 KeyVault 获取您的 RSA 密钥,用 EncryptPropertyAttribute 装饰您的指定属性,然后它会处理所有其他事情。

问题就在于此……我个人认为 KeyVault 的使用和管理有点迟钝。您必须使用 powershell 在您的应用程序和 keyvault 之间设置 oauth 身份验证,并且存储单个 RSA 密钥似乎需要大量开销。如果我们有数百个密钥要存储,我可以想象它会更有用。

有没有什么方法可以在不将 RsaKey 存储在 KeyVault 中的情况下使用 Microsoft 的所有客户端加密代码?

【问题讨论】:

【参考方案1】:

我花了一段时间才找到它,但是是的,您可以将 RSA 密钥存储在 KeyVault 之外。您只需要使用RsaKey 构造函数重载,它接收一个RSACryptoServiceProvider,您可以从您认为谨慎的任何地方获取它。我从我的 web.config 中取出我的。但是,我确保我的生产 RsaCsp 没有存储在源代码管理中,而是直接将其添加到 Azure Web App 配置屏幕中。

IKey tableStorageKey = GetTableStorageKey()
_tableRequestOptions = new TableRequestOptions

    EncryptionPolicy = new TableEncryptionPolicy(tableStorageKey, null)
;

...

private IKey GetTableStorageKey()

    using (var rsaCsp = new RSACryptoServiceProvider(2048))
    
        try
        
            //it doesn't really matter where you get your RsaCsp from, I have mine in my webconfig
            XmlDocument doc = new XmlDocument();
            doc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
            XmlElement node = doc.SelectSingleNode("/configuration/MyTableStorageRsaKey") as XmlElement;

            rsaCsp.FromXmlString(node.OuterXml);

            return new RsaKey("MyTableStorageRsaKey", rsaCsp);
        
        finally
        
            rsaCsp.PersistKeyInCsp = false;
        

    

【讨论】:

这是解决该问题的好方法。一般来说,这就是 Storage 使用 IKey 接口的原因——您可以实现自定义密钥算法或执行类似的操作并连接到自定义密钥服务。您似乎有自己喜欢的解决方案,但如果您想提交问题 here 或直接通过 microsoft dot com 的 emgerner 给我发电子邮件,我们很乐意就任何 KeyVault 可用性问题提供反馈和/或帮助您让它满足您的需求!【参考方案2】:

Microsoft.Azure.KeyVault.Cryptography 中,RsaKey 构造函数发生了变化。 现在它不再从RSACryptoServiceProvider 导入密钥,而是直接使用它,并在Dispose() 方法中处理它。所以用法会变成:

    public RsaKey GetFromXmlString(string xmlString)
    
        try
        
            var rsaCsp = new RSACryptoServiceProvider(2048, new CspParameters()  KeyContainerName = "MyTableStorageRsaKey" );
            rsaCsp.FromXmlString(xmlString);
            rsaCsp.PersistKeyInCsp = false;
            return new RsaKey("MyTableStorageRsaKey", rsaCsp);
        
        catch (Exception ex)
        
            throw new InvalidOperationException("Invalid rsa key xmlString provided", ex);
        
    

注意RSACryptoServiceProvider 的实例没有被释放。 还要注意RsaKeyIDisposable

【讨论】:

以上是关于不使用 KeyVault 的 Azure 表存储客户端加密的主要内容,如果未能解决你的问题,请参考以下文章

您应该为 VNET 专用终结点的每个 Azure 资源(CosmosDB、KeyVault、存储)创建多个子网还是只使用一个?

使用 Azure KeyVault 存储连接字符串与使用 ASP.net IIS_Reg 进行加密有啥区别?

Azure KeyVault - 签署 JWT 令牌

Azure 存储客户端加密

使用 ARM 模板将 Azure KeyVault 机密从 KeyVault 获取到应用服务

使用 Azure.Security.KeyVault.Secrets 的网络核心密钥保管库配置