I have a username and a password for an smtp server. Currently they are hardcoded in my code:
string userName = "username";
string password = "password";
Currently, anyone who disassembles my dll could see these strings, correct?
I wish to store these securely in the registry, in case of future changes to the smtp server, and/or the credentials. I am not worried about the smtp server address string's security. I am only worried about the credentials' security.
How do I do this without hard-coding the credentials anywhere? I wish to see encrpyted strings in the registry.
I can encrpyt the password, then store the encryption in the registry, delete the password from the code, and use the decrypted password assuming that it is correct. However, wouldn't someone who disassembles my code still be able to decrypt the encrypted string stored in the registry?
What is the safest way?
At some point, no matter how many layers of security you have, the code will have to use the unencrypted password. That means that someone with enough access to your system to view and/or modify the registry probably has plenty of access to your code to get your password no matter what you do.
I know as developers we tend to work with paranoia = Paranoia.Maximum;
a lot, but sometimes you have to back it down some.
That said, there are some things you can do. If the credentials need to be that secure, consider storing them, if possible, in a remote database. You can store them encrypted on a remote server so that anyone having access to your machine won't necessarilly have access to the DB Server.
If you really want to turn the paranoia up, and make security the user's responsibility at the same time, have them provide a "secure location" for a file that contains the data. You can then recommend that the location be something like a thumb-drive which would be removed physically from the computer when your program is not in use.
In any case, with security, you want to think in terms of layers. No one thing you do will be sufficient for really good security, but by layering several measures you can increase security to the point it should be sufficient for your needs.
The problem is not new. Operation system starting with Windows XP hat credential API which can be used in different scenarios. For example CredRead (see also http://www.pinvoke.net/default.aspx/advapi32/CredRead.html) and CredWrite can be used to save in encrypted form any general credential information. In the corresponding fields of CREDENTIAL structure you can define for exaple the level of persistence the saved credentials (logon session, all subsequent logon sessions on this same computer or to other logon sessions of this same user on this same computer and to logon sessions for this user on other computers).
If you want that your application only read the credential information you can use CredWrite in a separate configuration utility used by administrators or use the API as a part of setup of your application.