views:

650

answers:

7

What is the best way to store a user name and password for a Windows Service?

The service has to be able to access an MS SQL Server database on a remote machine. We have to support MS SQL Server authentication (mixed mode) instead of NT Authentication.

A: 

The best way to store the username is in plain text. The best way to store a password is not to store it at all, but only its hash. When you receive a login attempt, you hash the password and compare both hashes.

This is a little naive, though, as it is vulnerable to hash tables (wikipedia for rainbow table). This is easily avoided, anyway, storing a different salt for each user. A salt is simply a random number or string that you concatenate to the password prior to the hashing.

So the operations when trying to log in would be:

  1. Search the database for a hash and a salt related to the given login.
  2. Concatenate the given password with the previous salt.
  3. Hash the result of the concatenation.
  4. Compare the computed hash with the database one. If they match, grant access!
Alex Ati
This answer, unfortunately, is not related to the question. This is not a general password hashing question. He's talking specifically about sql server access from a service.
Michael Pryor
Ok, my bad, should have read carefully
Alex Ati
Besides storing the hash does not provide and substantial security gain since it's the hash that is used for authentication so gaining access to the hash is as good as gaining access to the password in cleartext.
Oliver Weichhold
I don't think so. Suppose you have my username and the hash of my password, then what? You put the hash as password in the form? If my code always computes a hash of the input, how can you execute the authentication check without rehashing the hash? Do you know what i mean?
Alex Ati
A: 

While I agree that, ideally, you would not need to store this password, if you do, there is no need to hash it yourself. CryptProtectData. Read the warnings at the bottom of this article. Though, I actually used LsaStorePrivateData, to store passwords.

Sanjaya R
I like how the first line in your LsaStorePrivateData link is "Do not use the LSA private data functions." :)
MusiGenesis
That line was _not_ there when I first used it. :)
Sanjaya R
+2  A: 

The DP API is the standard way of locally storing sensitive data on Windows. You didn't mention the programming language you're using, but in .NET this is exposed from the System.Security.ProtectedData class.

+5  A: 

Assuming .Net, you can encrypt your config file. See this.

JasonS
Thanks, but the service is not ASP.NET :)
Thomas Bratt
A: 

There is no truly secure way to store the username and password for your windows service, so it's very important that the account you're using to access SQL Server be given the barest minimum database permissions necessary to do whatever it needs to do.

Edit: and I don't mean that you shouldn't still encrypt the username and password - you should, using one of the tools mentioned in the other answers.

MusiGenesis
A: 

It depends on your environment.

Is this service running on an unsecured machine?

We have services that run inside of our firewall on servers inside our server room that only administrators have access to.

We deploy information like this right into the config files because we use NT Authentication to restrict access to THOSE files directly. But this is a case where the machine that runs the service is simply a server, not a user machine.

Jeff Sheldon
A: 

Thanks for the answers so far :)

The best approach seems to be to use a configuration file that encrypts the username and password using the following class: System.Security.Cryptography.ProtectedData

There is a good background explanation here: Windows Data Protection

Thomas Bratt