如何在Winforms应用程序中存储密码?
题
我在我编写的 winforms 应用程序中有一些类似的代码来查询用户的邮箱存储配额。
DirectoryEntry mbstore = new DirectoryEntry(
@"LDAP://" + strhome,
m_serviceaccount,
[m_pwd],
AuthenticationTypes.Secure);
无论我尝试什么方法(比如 SecureString
),我很容易就能看到密码(密码)使用 Reflector 或使用 Process Explorer 的字符串选项卡来执行可执行文件。
我知道我可以将此代码放在服务器上,或者使用委托等机制加强安全性,并仅向服务帐户授予所需的权限。
有人可以建议一种相当安全的方法来将密码存储在本地应用程序中,而不会将密码泄露给黑客吗?
哈希是不可能的,因为我需要知道确切的密码(而不仅仅是用于匹配目的的哈希)。加密/解密机制不起作用,因为它们依赖于机器。
解决方案
神圣的方法是使用 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,则任何有权访问该计算机的人都可以获取它。
其他提示
如前所述,数据保护 API 是实现此目的的好方法。请注意,如果您使用 .NET 2.0 或更高版本,则无需使用 P/Invoke 来调用 DPAPI。该框架使用 System.Security.Cryptography.ProtectedData 类包装调用。
我找到了 keith Brown 所著的《.NET 开发人员指南 Windows 安全》这本书。它有一些很好的示例,涵盖了各种安全场景。自由的 网络版 也可用。
如果将其存储为安全字符串并将安全字符串保存到文件中(可能使用 隔离存储, ,您只有在解密以创建 mbstore 时才会拥有纯文本密码。不幸的是,构造函数不接受 SecureString 或 Credential 对象。