关于安全性:如何在Winforms应用程序中存储密码?

How to store passwords in Winforms application?

我在一个winforms应用程序中编写了这样的代码,用来查询用户的邮箱存储配额。

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

无论我尝试什么方法(如SecureString),我都可以很容易地看到密码(m_pwd),无论是使用reflector还是使用process explorer的strings选项卡作为可执行文件。

我知道我可以将此代码放在服务器上,或者使用诸如委派之类的机制加强安全性,并且只给服务帐户所需的特权。

有人能在不向黑客透露密码的情况下,建议一种合理安全的方法在本地应用程序中存储密码吗?

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


认证方法是使用CryptoAPI和数据保护API。

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

1
2
3
4
5
6
7
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;

解密是相反的:

1
2
3
4
5
6
7
8
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本地计算机,那么加密的密码可以安全地存储在注册表或配置文件中,只有您可以对其进行解密。如果您指定了本地机器,那么任何有权访问该机器的人都可以得到它。


如前所述,数据保护API是一种很好的方法。请注意,如果您使用的是.NET 2.0或更高版本,则不需要使用p/invoke来调用dpapi。框架使用System.Security.Cryptography.ProtectedData类包装调用。


我找到了这本书,作者是KeithBrown,.NET开发人员的Windows安全指南。它有一些很好的示例,涵盖了各种安全场景。还提供免费的在线版本。


如果您将其存储为安全字符串并将安全字符串保存到文件(可能使用独立存储),那么只有在您解密它以创建mbstore时才会有纯文本密码。不幸的是,构造函数不接受SecureString或凭据对象。