简体   繁体   English

如何在Winforms应用程序中存储密码?

[英]How to store passwords in Winforms application?

I have some code like this in a winforms app I was writing to query a user's mail box Storage Quota. 我在winforms应用程序中有一些这样的代码我正在编写查询用户的邮箱存储配额。

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

No matter what approach I tried (like SecureString ), I am easily able to see the password ( m_pwd ) either using Reflector or using strings tab of Process Explorer for the executable. 无论我尝试什么方法(如SecureString ),我都可以使用Reflector或使用Process Explorer的字符串选项卡轻松地查看密码( m_pwd )以获取可执行文件。

I know I could put this code on the server or tighten up the security using mechanisms like delegation and giving only the required privileges to the service account. 我知道我可以将此代码放在服务器上,或者使用委托等机制加强安全性,并仅为服务帐户提供所需的权限。

Can somebody suggest a reasonably secure way to store the password in the local application without revealing the password to hackers? 有人可以提出一种合理安全的方法来将密码存储在本地应用程序中而不向黑客透露密码吗?

Hashing is not possible since I need to know the exact password (not just the hash for matching purpose). 哈希是不可能的,因为我需要知道确切的密码(不仅仅是用于匹配目的的哈希)。 Encryption/Decryption mechanisms are not working since they are machine dependent. 加密/解密机制不起作用,因为它们取决于机器。

The sanctified method is to use CryptoAPI and the Data Protection APIs. 成圣的方法是使用CryptoAPI和数据保护API。

To encrypt, use something like this (C++): 要加密,请使用类似这样的东西(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;

Decryption is the opposite: 解密是相反的:

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));

If you don't specify CRYPTPROTECT_LOCAL_MACHINE then the encrypted password can be securely stored in the registry or config file and only you can decrypt it. 如果您未指定CRYPTPROTECT_LOCAL_MACHINE,则加密的密码可以安全地存储在注册表或配置文件中,只有您可以解密它。 If you specify LOCAL_MACHINE, then anyone with access to the machine can get it. 如果您指定LOCAL_MACHINE,那么任何有权访问该计算机的人都可以获得它。

As mentioned, the Data Protection API is a good way to do this. 如前所述,Data Protection API是一种很好的方法。 Note that if you're using .NET 2.0 or greater, you don't need to use P/Invoke to invoke the DPAPI. 请注意,如果您使用的是.NET 2.0或更高版本,则无需使用P / Invoke来调用DPAPI。 The framework wraps the calls with the System.Security.Cryptography.ProtectedData class. 该框架使用System.Security.Cryptography.ProtectedData类包装调用。

I found this book by keith Brown The .NET Developer's Guide to Windows Security. 我发现这本书是由Keith Brown的.NET开发人员指南Windows安全性。 It has some good samples covering all kinds of security scenarios. 它有一些很好的样本涵盖了各种安全场景。 Free Online version is also available. 还提供免费在线版本

如果将其存储为安全字符串并将安全字符串保存到文件中(可能使用独立存储 ,则只有当您解密它以创建mbstore时才会有明文密码。不幸的是,构造函数不会使用SecureString或Credential对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM