43

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.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
AshtonKJ
  • 1,376
  • 2
  • 14
  • 22
  • There was a very similar question: http://stackoverflow.com/questions/126720/how-to-avoid-storing-credentials-to-connect-to-oracle-with-jdbc – David G Nov 03 '08 at 12:57
  • 1
    Oh, it didn't show up with any of the words I used for a search. If you want to close the question you can. – AshtonKJ Nov 03 '08 at 13:32

11 Answers11

17

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.
  • 23,793
  • 13
  • 94
  • 121
  • Correct, mostly to stop casual observers. WRT to your points: 1) Done. 2) Done. 3) Interesting idea. It might be worth testing Thanks – AshtonKJ Nov 03 '08 at 11:34
  • 1
    Are you saying there's no absolute way? – Kevin Le - Khnle Dec 22 '08 at 17:12
  • @Khnle-KevinLe If someone has access to all the software making the connection then you have no secrets from them. You can only make things harder to find. – WW. May 01 '14 at 01:24
10

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
  • 5,167
  • 6
  • 29
  • 32
4

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!

3

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
  • 31,315
  • 21
  • 88
  • 128
  • 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 – AshtonKJ Nov 03 '08 at 10:55
  • 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. – WhyNotHugo Aug 05 '09 at 14:23
2

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
  • 7,054
  • 8
  • 38
  • 44
  • 4
    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. – WhyNotHugo Aug 05 '09 at 14:20
0

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
  • 11,861
  • 2
  • 19
  • 20
  • 3
    You're thinking of user's passwords. This is the database password itself - which must be stored reversably. – Ian Boyd Feb 24 '10 at 18:46
0

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,308
  • 2
  • 19
  • 17
0

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
  • 1,584
  • 1
  • 12
  • 17
0

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
  • 13,277
  • 2
  • 41
  • 49
0

My interpretation of your question is that you are asking specifically how to store configuration passwords that your code will use to connect to services it depends on such as a database or third party API. In that case, you may want to consider using a service which provides a secrets container such as Hashicorp's Vault.

You can think of vault as a web service your application can connect to in order to lookup the secrets your application needs at application runtime.

As an example, lets assume your application needs to connect to a database but you don't want to store your database credentials with your application source code in your version control system. Furthermore, lets assume that you want the database credentials used by your application to be different each time your application starts. In this case, you could enable and configure the database secret back end in vault. This means that vault will dynamically create your database credentials as a service, and then provide your application with a revocable leased token for some duration of time. Vault, of course, will allow you to store any secret in it.

Vault provides secure ways for your application to connect to it. One such authentication method uses what is known in vault as the Cubbyhole Secrets Engine.

axiopisty
  • 4,972
  • 8
  • 44
  • 73
-2

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
  • 1,404
  • 4
  • 21
  • 40
  • 3
    You're thinking of user's passwords. This is the database password itself - which must be stored reversably. – Ian Boyd Feb 24 '10 at 18:46