使用.Net进行加密数据的持久化存储

19

我需要在应用程序运行期间存储加密数据(几个小字符串)。我不希望用户每次启动应用程序时都需要提供口令。即,在安全存储加密密钥方面存在挑战。

我一直在研究 RSACryptoServiceProvider 和使用 PersistentKeyInCsp,但我不确定它的工作原理。密钥容器是否在应用程序运行期间或机器重启后保持不变?如果是,它是特定于用户还是特定于机器的?也就是说,如果我在用户的档案文件夹中存储我的加密数据,那么当用户登录不同的机器时,我能否解密数据?

如果上述方法行不通,我有哪些选项(我需要处理漫游配置文件)。

2个回答

38
数据保护API(DPAPI)正是您想要的。它使用机器或用户凭据作为加密密钥,对任意数据进行对称加密。您无需担心管理密钥;Windows会为您处理。如果用户更改密码,Windows将使用用户的新密码重新加密数据。
在.NET中,DPAPI通过System.Security.Cryptography.ProtectedData类公开。
byte[] plaintextBytes = GetDataToProtect();
byte[] encodedBytes = ProtectedData.Protect(plaintextBytes, null, DataProtectionScope.CurrentUser);

Protect方法的第二个参数是一个可选的熵字节数组,可以作为额外的应用程序特定"秘密"使用。

要解密,请使用ProtectedData.Unprotect调用:

byte[] encodedBytes = GetDataToUnprotect();
byte[] plaintextBytes = ProtectedData.Unprotect(encodedBytes, null, DataProtectionScope.CurrentUser);

DPAPI可以与漫游配置文件(如此处所述)正确配合使用,但您需要将加密数据存储在各个计算机都可以访问的位置(网络共享、具有IsolatedStorageScope.Roaming的IsolatedStorage等)。

有关更多信息,请参见MSDN中的ProtectedData类。此处有一份DPAPI白皮书,其中包含比您想要的更多信息。


仅供记录,您需要查看其他代码来处理将其持久化到更“公共”的位置(例如至少在您的内部网络上),以便他们可以从其他计算机访问它。通常,您可以使用Environment.SpecialFolder.ApplicationData来获取特定于机器和用户的位置。 - Sean Hanley
谢谢你的回答,这应该可以解决问题。你有没有想过如何在1.1版本中实现呢?ProtectedData是.Net 2.0中新增的功能。 - Sunny Milenov
1
要在.NET 1.1中使用DPAPI,您需要使用P/Invoke。请参阅此处以获取相当完整的演示: http://msdn.microsoft.com/en-us/library/aa302402.aspx - Michael Petrotta
@Michael Petrotta - FYI,解密示例的第二行有一个错误的[]。(尽管如此,非常感谢您提供的简单示例!) - paytools-steve

0

我想补充DPAPI方法。

虽然我自己没有实现用户存储方法,但是微软有一份文档介绍了用户存储方法,可以为特定用户加密和解密数据。

我使用的是机器存储的DPAPI。如果符合您的需求,我可以描述一下它的使用方法。我使用了一个Windows服务来加载Windows用户配置文件,该用户的密码用于加密数据。

顺便说一句,DPAPI使用Triple-DES加密算法,可能比AES弱一些,但我不确定您需要什么类型的保护。

Windows数据保护 http://msdn.microsoft.com/en-us/library/ms995355.aspx


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接