32

我在编写用于查询用户邮箱存储配额的 winforms 应用程序中有一些这样的代码。

DirectoryEntry mbstore = new DirectoryEntry(
      @"LDAP://" + strhome, 
      m_serviceaccount, 
      [m_pwd], 
      AuthenticationTypes.Secure);

无论我尝试了哪种方法(例如SecureString),我都可以使用 Reflector 或使用 Process Explorer 的字符串选项卡来轻松查看密码( m_pwd )作为可执行文件。

我知道我可以将此代码放在服务器上,或者使用委托等机制加强安全性,并只为服务帐户提供所需的权限。

有人可以建议一种相当安全的方法来将密码存储在本地应用程序中而不向黑客泄露密码吗?

散列是不可能的,因为我需要知道确切的密码(不仅仅是用于匹配目的的散列)。加密/解密机制不起作用,因为它们依赖于机器。

4

4 回答 4

25

神圣的方法是使用 CryptoAPI 和数据保护 API。

要加密,请使用类似这样的东西(C++):

DATA_BLOB blobIn, blobOut;
blobIn.pbData=(BYTE*)data;
blobIn.cbData=wcslen(data)*sizeof(WCHAR);

CryptProtectData(&blobIn, description, NULL, NULL, NULL, CRYPTPROTECT_LOCAL_MACHINE | CRYPTPROTECT_UI_FORBIDDEN, &blobOut);
_encrypted=blobOut.pbData;
_length=blobOut.cbData;

解密则相反:

DATA_BLOB blobIn, blobOut;
blobIn.pbData=const_cast<BYTE*>(data);
blobIn.cbData=length;

CryptUnprotectData(&blobIn, NULL, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &blobOut);

std::wstring _decrypted;
_decrypted.assign((LPCWSTR)blobOut.pbData,(LPCWSTR)blobOut.pbData+blobOut.cbData/sizeof(WCHAR));

如果您不指定 CRYPTPROTECT_LOCAL_MACHINE,则加密密码可以安全地存储在注册表或配置文件中,并且只有您可以解密它。如果您指定 LOCAL_MACHINE,那么任何有权访问该机器的人都可以获得它。

于 2008-09-02T22:58:13.183 回答
12

如前所述,数据保护 API 是实现此目的的好方法。请注意,如果您使用的是 .NET 2.0 或更高版本,则无需使用 P/Invoke 来调用 DPAPI。该框架使用 System.Security.Cryptography.ProtectedData 类包装调用。

于 2008-09-30T22:20:11.583 回答
4

我找到了 keith Brown 的这本书 .NET Developer's Guide to Windows Security。它有一些很好的样本,涵盖了各种安全场景。免费在线版本也可用。

于 2008-09-07T20:34:26.290 回答
2

如果您将其存储为安全字符串并将安全字符串保存到文件中(可能使用独立存储,您将拥有纯文本密码的唯一时间是解密它以创建您的 mbstore。不幸的是,构造函数不采用SecureString 或 Credential 对象。

于 2008-09-02T22:57:09.783 回答