views:

64

answers:

6

I am in the planning stages of a .NET desktop app that will communicate with a web service. The web service requires a username and password, and a common feature in this sort of app is to save the user's credentials for the next logon (just a simple 'log me in automatically' checkbox).

I've thought of a few ways of achieving this, but I am not sure what the most secure way would be. Should it be stored encrypted in a file (and could someone nefarious copy that file to their own machine and hence logon as the original person), or in the registry somehow (I've not done any registry work before, is it secure and would it work)? Are there any other options I might not have thought of?

(Edit to clarify: The application will be available on the internet, so users will be running this on their own machines - while I understand there's a certain cutoff point in terms of security since I can't insist people use firewalls and anti-malware programs, I want to make it at least a little difficult for someone to gain unauthorised access.)

A: 

I cannot imagine why would someone try to find the password, when he or she could log on without entering it (because you auto-complete it). I am getting it wrong ?

Btw, make sure you are using https for communication.

thelost
The person "stealing" the file might not have physical access to the machine to run the application, but can access files through some sort of backdoor or trojan. I could imagine it happening in our IT department (who can remotely access files/folders of remote PCs but cannot physically access the keyboard/mouse etc.)
Andy Shellam
Thanks for the hint! I find it a bad approach to share your program files (if you store you application encrypted data in there), though.
thelost
You don't have to share your program files for them to be "stolen" - think trojans, back-door viruses, even cookies can be stolen (XSS in websites.) In our IT department users don't know that we have full access to their machines files (for troubleshooting purposes of course.) Plus the users may not even know that the app has encrypted their password in a file either, they just think "oh it's remembered my password."
Andy Shellam
A: 

Encryption would be the way to go. I did the same thing with an internally-used application which encrypted the username and password in an XML file.

As for people wanting to copy the file onto another machine, you could do something like concatenate the machine name and IP address (and any other property relatively uniquely identifying the machine) and encrypt that string as part of the saved credentials file.

Then when your app re-reads that file to process the logon, if it does the same encryption of the machine name/IP address/etc it's running on but comes up with a different hash to the one that's stored in the file, your app will know the file has been copied to a different machine, it can discard it, and prompt for the logon details.

Andy Shellam
Wouldn't it be kind of odd for an application to re-ask for you password whenever you got a new IP address? Or if the machine name changed?
mlsteeves
No, not really. How many times does your machine name change? Or IP address? In 5 years at my last place, my IP address never changed nor my machine name. At home my broadband IP address changes about every 10 days. The application I did this on expired the "saved credentials" file every day anyway so the users had to enter their password at least once a day, and this way they didn't forget them as easily!
Andy Shellam
A: 

If you can store the credentials and later retrieve them, someone else can also retrieve the credentials.

If you still want the ability to remember the credentials I'd suggest storing them on a USB stick which the user can bring with him/her. In this way the credentials are not compromised if the computer is. (Unless the USB stick is connected to the computer at the time).

Sani Huttunen
A: 

The problem with client software where data is not loaded externally (e.g.: the password to decrypt the file) is vulnerable.

What you could try to do, is encrypt the information using RSA keypair and the key being comprised of data that is unique to their current loaded user profile (that can only be obtained easily using the same user profile on the same machine) and store the hash in the registry.

The registry is like a file to you in this situation, just you can attempt to make it less transparent to the user using it.

Kyle Rozendo
+3  A: 

Windows has a facility to store user credentials securely. I found this article to be the best: http://blogs.msdn.com/peerchan/pages/487834.aspx

mlsteeves
This looks like exactly what I need, thank you!
pete the pagan-gerbil
+1  A: 

I asked (and subsequently answered) a very similar question a while back. The intended way of doing this is to use the ProtectedData class, which includes an option to add addition encrypted based on the current user.

byte[] dataToEncrypt = new byte[] { ... }; 

// entropy will be combined with current user credentials 
byte[] additionalEntropy = new byte { 0x1, 0x2, 0x3, 0x4 }; 

byte[] encryptedData = ProtectedData.Protect( 
    dataToEncrypt, additionalEntropy, DataProtectionScope.CurrentUser); 

byte[] decryptedData = ProtectedData.Unprotect( 
    encryptedData, additionalEntropy, DataProtectionScope.CurrentUser); 
Richard Szalay