views:

2963

answers:

10

I have a database that many different client applications (a smattering of web services, some java apps and a few dot net applications) connect to. Not all of these are running on windows (Sadly, otherwise it would make this an easy answer question with just enabling windows authentication for database connections). At the moment, the passwords are stored in various configuration / properties files lying around the systems. Ideally, only the support staff have access to the servers where the files are running, but if someone else gains access to one of the servers, they would have enough database permissions to get a fair whack of data as it stands now.

My question then, What is the best way to keep the passwords configurable, without having it too easily available to the casual human reader?

Edit Just to clarify, DB server is Windows Server 2003, running MSSQL 2005.

PS: I don't see any questions that this duplicates, but if there are, please feel free to close this one.

+2  A: 

Don't use passwords, server to server authentication can usually be performed by using a key file or a client cert or some other way other than a password.

paan
1) This doesn't work for desktop apps, since it would mean it bundles the cert. (2) Someone can get hold of the cert in the same way as someone might get access to the source.
Hugo
A: 

You could use a reversible encryption algorithm e.g. Blowfish to store the passwords as a stopgap measure. There should be a number of free libraries you can use to build this into all your programs that need this access.

Bruce Schneier's page on Blowfish

Wikipedia article on Blowfish

Bork Blatt
+3  A: 

At my old workplace we used to have a system whereby all passwords were encrypted (using Triple DES or whatever we were using at the time). The passwords were often stored in properties files (this was in a Java system).

When the password needed to be changed, we could simply use "!plaintext" as the value, and then our code would load it up, encrypt it, and store the encrypted value back in the properties file.

This meant that it was possible to change the password without knowing what the original value was - not sure if that's the kind of thing you were asking for!

Phill Sacre
+2  A: 

It sounds like there is no easy answer (because of the different types of applications that connect)... really, the only issue I see is the Java Apps which seem to connect directly to your database. Is that correct?

If so, here's what you can do:

1) Change any client-side applications that connect directly to the DB to go through a service. (If they have to connect directly, then at least give them a first step to "get password" from a service, then they can connect directly).

2) Store the passwords in the web.config file (if you chose to do .Net web services), and then encrypt the "connection strings" section of the file.

Timothy Khouri
Yep, some of the java systems do connect directly to the DB. It is an old system that has grown quite organically. But these are some good suggestions. Thanks
Furis
Client-Server apps is the best choice. A service shouldn't grand the DB password, since you'd have the same problem. ALL services should be available though the java server, no desktop app should connect directly to the DB.
Hugo
+5  A: 

I'm assuming you want to hide the passwords from casual observers. If they were evil, steely eyed observers with access to all the source code on one of the machines that connects, then they can get the password with a bit of reverse engineering.

Remember that you do not need to use the same protection for each different client. A few steps:-

  1. Create different database accounts for different systems that access your database
  2. Limit access on the database to only what they need using your inbuilt database GRANTs
  3. Store a triple DES (or whatever) key inside a password manager class on your database. Use this to decrypt an encrypted value in your properties file.

We have also considered having the application prompt for a pass-phrase on startup but have not implemented this as it seems like a pain and your operations staff then need to know the password. It's probably less secure.

WW
Correct, mostly to stop casual observers. WRT to your points:1) Done.2) Done.3) Interesting idea. It might be worth testingThanks
Furis
Are you saying there's no absolute way?
Khnle
A: 

For the java stuff, if you're using an app server see if you can define a data source, and your apps can get at the data source using JNDI. That way, managing the datasource (including connection details) is handled by the app server, and your application code has to do is ask for a datasource.

tunaranch
A: 

NTLM Authentication or LDAP-based (Active Directory) authentication should be available to you with a bit of effort. This would allow you to use your "windows authentication" across applications.

It may mean a bit of a migration for your operations staff, but SSO for a set of applications is nice.

Ken Gentle
Clearly specified not all run on windows. LDAP on non-windows clients could be troublesome.
Hugo
+3  A: 

Let's assume the following common scenario:

  • You use the same code base for all environments and your code base has the database passwords for each environment.

  • The personnel (sysadmins, configuration managers) that have access to your production application server are allowed to know the production database passwords and no one else.

  • You don't want anyone with access to the source code to know what the production passwords are.

In a scenario like this, you can encrypt and store the production passwords in property files that your application. Within the application you can include a class that reads the passwords from the property file and decrypts it before passing it to the database driver. However, the key and the algorithm used to decrypt the password are not part of the source code but rather passed to the application as a system property at runtime. This decouples the knowledge of the key from the application source code and anyone with access to just the application source code will no longer be able to decrypt the password because they do not have access to the application's runtime environment (app server).

If you are using Java take a look at this for a more concrete example. The example uses Spring and Jasypt. I am confident that some thing like this can be extrapolated to other environments like .Net

neesh
A: 

Using encryption is not a good idea. If someone compromize the key he can decrypt it. Use a hash algorith with salt to store paswords. Hash algorithms are one way so its not reversible. But they are vulnerable to dictionary attacks so use salt (concatane plain text with something long and verbose than hash it). It also protect database from internal attacks.

Gok Demir
You're thinking of user's passwords. This is the database password itself - which must be stored reversably.
Ian Boyd
A: 

Yes I have to agree with the option of storing the (salted) hashes. I would recommend a (salted) SHA256 hash of the password stored in the database. Also don't forget to enforce secure password rules.

meme
You're thinking of user's passwords. This is the database password itself - which must be stored reversably.
Ian Boyd