I have some code like this in a winforms app I was writing to query a user's mail box Storage Quota.
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.
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.
As mentioned, the Data Protection API is a good way to do this. Note that if you're using .NET 2.0 or greater, you don't need to use P/Invoke to invoke the DPAPI. The framework wraps the calls with the System.Security.Cryptography.ProtectedData class.
If you store it as a secure string and save the secure string to a file (possibly using Isolated Storage, the only time you will have a plain text password is when you decrypt it to create your mbstore. Unfortunately, the constructor does not take a SecureString or a Credential object.
The sanctified method is to use CryptoAPI and the Data Protection APIs.
To encrypt, use something like this (C++):
Decryption is the opposite:
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. If you specify LOCAL_MACHINE, then anyone with access to the machine can get it.
I found this book by keith Brown The .NET Developer's Guide to Windows Security. It has some good samples covering all kinds of security scenarios. Free Online version is also available.