What is the best way to keep passwords configurable, without having them too easily available to the casual human reader?

StackOverflow https://stackoverflow.com/questions/258299

  •  06-07-2019
  •  | 
  •  

Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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

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!

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.

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.

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

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.

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.

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top