views:

134

answers:

5

My web application stores external website login/passwords for interaction with them. To interact with these websites I need to use the original password text, so storing just the hash in my database is not going to work.

How should I store these passwords?

Edit: I am concerned if someone gets access to my server. If I use some kind of 2-way encryption and they have server access then they can just check how the passwords are decrypted in my backend code.

+3  A: 

If you MUST do this, you should use a two-way encryption. There are a lot algorithms (ciphers) for this, but basically you encrypt your data with an encryption key, and use the same key for decrypting them again.

Choosing the right cipher depends on which are supported by the programming language of your choice, but examples are:

  • Blowfish
  • 3DES
  • Skipjack

They come in different complexity and some are harder to crack than others. You should realize though, that no two-way encryption is safe from cracking, given enough time. So it all depends on, how sensitive these passwords are.

/Carsten

Carsten Gehling
OK, but where do you store the encryption key? Seems to me like you just moved the problem to a different place.
Mike Baranczak
that's what I am worried about -if someone gets access to my server then they can work out the original passwords whether they are encrypted or not.
Plumo
@Mike: Agreed. But depending on Richard's setup, the database data might be "easier" to get access to (from a crackers perspective) than the filesystem. So all of our answers depends on what kind of threat Richard wants to eliminate.
Carsten Gehling
@Richard: "Get access to your server" - do you mean physically (stolen) or through e.g. SSH? If the former, then go with slartibartfast's suggestions. If the latter: As I said earlier, no two-way encryption is totally safe. Your money is best spent on ensuring that no one gets access to your server: SSH instead of Telnet, SFTP instead of FTP, all sensitive HTTP transactions through SSL, etc. etc.
Carsten Gehling
through ssh - server is hosted securely
Plumo
I would say that my suggestion would be moderately effective against someone who gains any logical access to the database. If access is just to the database (and not system memory), you could be pretty safe. If they have undetected / unrestricted access to the server as a whole for a period of time, yes, information will be exposed, and no, you can't prevent that, regardless of mechanism.
Slartibartfast
+3  A: 

Decide what you are protecting them against. Options include (but are not limited to): Accidental disclosure, disclosure by you, disclosure in transmission, disclosure due to code error, disclosure due to physical theft of hardware, etc.

If this is a web application, and each user is storing his/her own set of passwords, then you might encrypt these passwords with their login password to your application. If this is an application that each user installs separately, and which keeps its own local database, you could have an optional master password (like Firefox does).

If you are just ensuring that the data is safe if the hardware is stolen, you might use a full disk encryption solution like TrueCrypt or PGP WDE, or Ubuntu, Debian, or Fedora's built-in approach, and require a PIN or password on every boot.

If you just care about secure transmission, have code to ensure that you use transport security, and don't worry about encrypting the data in your database.

Slartibartfast
yeah it is a web application and I am concerned about someone getting access to the server where the database and backend code is readable
Plumo
So encrypt (symmetric) the passwords in the database with the user's login password or a derivative of it as the key (e.g. secure_hash(constant_server_secret + user_password) )You keep that key in memory only as long as their session is active, discarding it when their session expires or they log out. Don't send it to the user; they don't care and it exposes the key.The only passwords an attacker (or even you yourself) has access to are those of users with active sessions, and then only with careful scouring of the current state of memory.
Slartibartfast
+3  A: 

It seems to me that you want to store passwords in a similar fashion as Firefox and Chrome. So why not look at how they do it?

This is how Chrome does it: http://www.switchonthecode.com/tutorials/how-google-chrome-stores-passwords

Erik B
The interesting part is at the very end: "CryptProtectData, which is a Windows API function for encrypting data. [...] It can only be decrypted on the same machine and by the same user..." It doesn't tell us how the encryption works, or what the alternatives are for other platforms, so I'm not sure if it's directly applicable.
Mike Baranczak
+3  A: 

Hey Richard,

I would go about this in the following way.

Protect data against hardware being stolen:

Use disc encryption as discussed in previous posts.

Protecting data if server is compromised (hacked):

I would use two different servers for this project, one worker server and one front server.

A) Worker server

  • This has the DB with passwords etc, it also connects to other services.
  • To connect to worker server, users can do it through an API. API should have on function, insertUserData, which allows userdata to be inserted, API escaped all the input.
  • API uses a DB user which only has input privilegies on the userData table.
  • This would be the only way to contact this server.
  • Only allow SSL connections.
  • This server in turn runs chron jobs that connect to external services, pulls data from them and populate it's DB. Use a different DB with different user privileges.
  • This server runs another chron JOB which connects to the front server and pushes new data to front server.
  • Minimal amount of services running
  • Only SSH/SCP from your IP, tight firewalling. Block if connections exced X / min etc as they only would do an occasional insert.
  • NO FTP etc.

B) Front server

Receives data from Worker server, never uses the passwords itself. Only way to contact worker server is through API mentioned above, only for new user information. This is where all users login to see their information etc.

The problem with doing it all on the same server, if you get hacked the hacker can sit and sniff all incoming data / passwords etc.. so even if they are stored / encrypted / decrypted securely, with some patience he would sniff them all.

samuelf
I do realize if a hacker gets access to worker server, you're screwed but this would make it close to impossible. You could also add that the API on worker server calls a stored procedure in turn..
samuelf
+1  A: 

When the application is first run, it will generate a random key. This key will be used to encrypt and decrypt sensitive data. Store the key in a local file, and set the file permissions so that nobody else can read it. Ensure that the user running the web server has no login access (this is a good idea anyway).

Possible ways to break this system:

  1. Get root access.
  2. Get sudo access.
  3. Deploy a malicious application on the web server - this application will then have access to the key, and may be able to send it elsewhere.

As long as you take reasonable precautions against all of these, you should be OK.


EDIT: Come to think of it, you could just store the sensitive data right in the key file. Encryption would provide an extra layer of security, but it wouldn't be a very strong layer; if an attacker gets access to the file, chances are good that he also has access to the DB.

Mike Baranczak