首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何保护AesCryptoServiceProvider的rgbKey?

如何保护AesCryptoServiceProvider的rgbKey?
EN

Stack Overflow用户
提问于 2013-03-14 16:08:32
回答 1查看 899关注 0票数 1

我们有保存用户/密码和一些其他数据的表。每条记录的密码字段必须加密。我们决定使用AesCryptoServiceProvider进行加密,并手动创建了一次rgbKey。然后加密所有用户密码,并将记录插入到表中,其中密码字段使用rgbKey加密。

我们在负载均衡器后面有几个服务器,每个服务器都应该读取这些记录,并可以解密密码字段的值。一开始,我们将base64StringFormat中的rgbKey放入我们的动态链接库( API )中,同样,所有服务器都将使用这个API,并且可以解密加密值。

但是,将rgbKey保存在dll文件中是非常不安全的。我们讨论了是否将密钥保留在DPAPI中。在解密时,在我们的任何服务器上,我们将从DPAPI获得密钥,并成功解密加密值。

我想我可以在当前用户模式的任何服务器上生成一次受保护的密钥,然后将它保存在我们通用的dll中。每个服务器使用公共的动态链接库,将这个受保护的密钥(byte[])提供给同一个用户的DPAPI,就可以得到不受保护的密钥值。然而,它只能在受保护的机器上工作,在其他机器上,它会给出错误:"Key not valid for use in specified state“。

我的问题是,如何保护我的永久rgbKey,以便我可以从所有计算机访问它?看看下面类似的测试控制台应用程序,我的方法有什么问题?

我给出了我的测试控制台应用程序的示例代码:

首先,我在本地机器上运行我的PDPAPI()函数:

代码语言:javascript
复制
    static void PDPAPI() {
        System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
        byte[] rgbKey = encoding.GetBytes( "MyRgbKey" );
        byte[] protectedData = ProtectedData.Protect( rgbKey, null, DataProtectionScope.CurrentUser );
        string base64ProtectedData = Convert.ToBase64String( protectedData );
        Console.WriteLine( "base64ProtectedData:{0}", base64ProtectedData );            
    }

然后硬编码添加到我的UDPAPI()函数,从上面的执行中获得base64ProtectedData值,重新构建解决方案:

代码语言:javascript
复制
    static void UDPAPI() {
        string base64ProtectedData = "****";
        byte[] protectedData = Convert.FromBase64String( base64ProtectedData );
        byte[] unProtectedData = ProtectedData.Unprotect( protectedData, null, DataProtectionScope.CurrentUser );
        string base64unProtectedData = Convert.ToBase64String( unProtectedData );
        Console.WriteLine( "base64unProtectedData:{0}", base64unProtectedData );
    }            

现在,如果我在本地机器上运行UDPAPI()函数,它会成功地解除对数据的保护,但是,如果我将控制台应用程序迁移到任何其他服务器,并以网络用户身份登录到该服务器,控制台应用程序会给出错误消息"Key not valid for use in specified state“。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-14 21:19:03

老实说,对于密码加密,如果使用单向散列,然后不使用密码的明文,只需散列用户输入并进行比较,就不会有密钥存储问题。在C#中典型的用法是PBKDF2 (Rfc2898DeriveBytes)。有关其他选项,请参阅Crypto:What makes a hash function good for password hashing?

要使用DPAPI,您必须在每个服务器上分别加密您的密钥(这并不是一件坏事)。

最好不要硬编码你的密钥,这不是因为它可以被访问,而是因为当你需要时,或者在不同的设置中,它更容易改变。通常,在没有专门硬件的情况下,您可以做的最多的事情就是将密钥与数据分开。您可以通过加密密钥来使事情变得更加困难,但您只是添加了攻击者也必须访问的另一个密钥,没有理想的解决方案。

如果你想要一种简单的方法来改变你的密钥随着时间的推移,我已经移植了keyczar framework to c#它有必要的机制来轮换密钥,以便您仍然可以解密旧数据,同时加密新数据,但它并没有真正提供任何更安全明智的密钥存储可访问性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15404055

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档