Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Short version: I want "Login on program startup" checkbox like in Skype, for example, but don't know how to protect saved credentials securely.


I'm writing client application which, before doing actual requests to server, should be authorized by server. Authorization goes as follows: user fills in standard login dialog, data goes to server via HTTPS and, if it was correct, server sends credentials.

However, entering password each time is disturbing and prevents starting application on system startup. I want to encrypt those credentials and save them on disk. I could not find appropriate encryption key, however.

Key should be, obviously, user-specific (not system-wide!) and reasonably hard to fraud.

For now I just use hash of some HDD info and username and fallback to hash of process environment, if WinAPI call fails (how bad is that?).

I'm writing for Windows using C++/Qt, but any recommendation is welcomed. Thanks.


upd1

Ok, to make myself clear:

  1. Required encryption level is:
    you cannot login by simply copying credentials.dat file from one computer to other (or one user folder to other);
  2. Keeping password secure (which is not stored by application) is user's responsibility.
  3. I want to store not the password, but encrypted access token which is user-id and public key for encrypting communications with server.

From your answers I've understood that my auth. system isn't okay. I will reconsider it. And yes, I have access to both, server- and client-side.

For now, I want way to determine machine- and user-unique encryption key, which I can get from OS in runtime to decrypt/encrypt credentials (which is server's answer to email/password entered by user).

share|improve this question
    
Please see stackoverflow.com/questions/1262081/… –  PlayDeezGames Mar 14 '12 at 16:44
    
It is important to determine "how much" security you have to have. Absolute security is not always trivial to accomplish and is not always required. –  Emmad Kareem Mar 14 '12 at 18:36
    
@PlayDeezGames I know how and what to encrypt, but not sure with what key. –  elmigranto Mar 15 '12 at 13:15
    
That part's easy! Pick something. Or generate something. –  PlayDeezGames Mar 15 '12 at 13:41
add comment

3 Answers

You could do some basic CHAP style method.

Example:

Client and server have a shared private key for each client user.

  • User authenticates first time; server returns a pass token (guid)
  • pass token is stored client end.
  • Upon "Login on program startup", client requests access.
  • Server responds with an "access token" and pre-computes the response (shared private key + access token + pass token)
  • client responds by giving the HASH of (shared private key + access token + pass token).

  • Pass token is valid until the user logs out.

EDIT: I have done something similar to this for a web service, a little more involved but on the same principles.

share|improve this answer
    
That's great, thanks. I will consider reimplementing auth. system, but now I have other priorities (see upd1). –  elmigranto Mar 15 '12 at 13:17
add comment

If your application needs to supply the username and password every time, then one way or another, you will be storing them locally (obfuscated somehow, or not).

If you can change the server-side authentication, you could implement an access token-based authentication (as in Darknight's answer), which is what I would favor myself. That way, you avoid actually storing passwords on the user's hard drive.

If you have no control over the server-side, and must supply username and password each time, I would agree with Tom Squires that you should store them as simply as possible.

Why? Because to do anything else is to provide a false sense of security to the user. For a full argument, you should read "Plain Text Passwords" on the Pidgin wiki.

You should read that page for the full argument, but to briefly summarize:

  • Any obscured password (anything that isn't hidden behind another password) can eventually be un-obscured.
  • Not only can it be un-obscured, but a utility could be made that would return you the plain-text password with a single button-press.

If you have physical access to the computer, passwords aren't relevant.

share|improve this answer
    
That maybe true for UNIX where files indeed are more secure, but on Windows I want to protect credentials.dat file on PC1 from being applicable on PC2 after copying. –  elmigranto Mar 15 '12 at 13:21
add comment

You can encrypt it and store the credential info on the client side using any strong and recommended algorithms like SHA-1. But do not store the key used for the encryption on the client side. Let only your server know the key which can decrypt the data.

To keep the client and server in sync, you can ask user to Login/Register into your website and then provide him the link for downloading the application. While creating the application link implant a seed into the application and store the same against the user ID in your server side DB. Use this seed to encrypt and store the credentials on client side and delete the seed after first successful login.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.