我在winforms应用程序中有一些这样的代码,我正在编写查询用户的邮箱存储配额。
DirectoryEntry mbstore = new DirectoryEntry(
@"LDAP://" + strhome,
m_serviceaccount,
[m_pwd],
AuthenticationTypes.Secure);
无论我尝试什么方法(如SecureString
),我都可以轻松地使用Reflector或使用Process Explorer的字符串选项卡查看密码( m_pwd )。
我知道我可以将此代码放在服务器上,或者使用委托等机制加强安全性,并仅为服务帐户提供所需的权限。
有人可以建议一种合理安全的方法将密码存储在本地应用程序中,而不会泄露黑客的密码吗?
哈希是不可能的,因为我需要知道确切的密码(而不仅仅是用于匹配目的的哈希)。 加密/解密机制不起作用,因为它们与机器有关。
答案 0 :(得分:24)
神圣的方法是使用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,那么任何有权访问该计算机的人都可以获得它。
答案 1 :(得分:11)
如前所述,Data Protection API是一种很好的方法。请注意,如果您使用的是.NET 2.0或更高版本,则无需使用P / Invoke来调用DPAPI。该框架使用System.Security.Cryptography.ProtectedData类包装调用。
答案 2 :(得分:4)
我发现这本书是由Keith Brown撰写的.NET开发人员Windows安全指南。它有一些很好的样本涵盖了各种安全场景。 免费Online version也可用。
答案 3 :(得分:2)
如果您将其存储为安全字符串并将安全字符串保存到文件中(可能使用Isolated Storage,则只有在您解密它以创建mbstore时才能使用纯文本密码。不幸的是,构造函数不接受SecureString或Credential对象。