views:

134

answers:

3

This is not the usual question "Is it safe to store plain-text users' passwords?". No, it's not safe, we all know that.

I'm writing a little application that should authenticate against an external system to do some stuff, and the only available authentication method is through a username and a password. It was intended for humans, and cannot be changed.

There are multiple users that have access to my application and each one is authenticated separately, however they all "share" the same authentication data against the external system, which ideally is managed transparently by the application.

The "dumb" solution is to store username/password in plain-text and use it for authentication, but obviously this is not safe. Passwords could be encrypted, but what if someone breaks into the system?

Possible solution: use DPAPI to encrypt/decrypt the password (and maybe even the username) transparently. Is this a good idea? Is this safe? What about setups with multiple machines (is encryption compatible between machines)?

Do you have any additional suggestion?

+2  A: 

DPAPI cannot usually be used in web farms - the key store is specific to the machine. You didn't specify if certain users share one set of credentials while another user shares another set of credentials. If all users share the same set of credentials, store it in the web.config and be done with it. Secure the credentials using either the configuration encryption API or simple ACLs on the web.config file.

If different users have different third party system credentials, I'd store the credentials with the user, using a hash of the user's password + a salt as the encryption key. Then, even if a malicious user gets your database, they'd have to be able to first decrypt your user's password before even attempting to hack the third party password. The salt adds an additional layer of difficulty in doing so.

Chris
The add-user script will need to know the credentials of course..
Will
The problem with encrypting with the user's password hash (plus salt) is that it's hard to add new users after setting things up because you need the password of someone else (e.g. the admin that is adding users). Also, if a user changes her password you have to re-encrypt her "copy" of the external system credentials. It could be a viable solution, although a bit convoluted.
Dario Solera
@Dario I'm not sure I understand the complexity. Given the OP, I assumed the user provided the third party credentials after setting up their initial account (or accessing it for the first time). Given that the user's password would already be available in hash form at that point, it would be trivial to encrypt any credentials provided by the user using said hash + a salt. Yes, you'd have to re-encrypt the credentials every time the user changed their main password, but this hardly seems an uncommon requirement.
Chris
+1  A: 

Remember that DPAPI keys are at the user level. Unless you're going to set up and store a separate copy of the credential set for each user, DPAPI won't do you any good. The only really secure way to do this would be with a "trusted subsystem" model where you have a Windows Service running as some user, with the protected data stored in that user's HKCU hive encrypted with its DPAPI key. It performs all the actions to the system requiring authentication on behalf of the user, and the username/password aren't loaded into the user's process. Even with that, if the user is an admin, they could technically still get ahold of the username/password by debugging the service process.

The really safe way to do it would be to do the same thing, but remote- use Windows credentials to auth the user to a remote server that takes action on behalf of the users. Really just depends on how secure that username/password needs to be.

nitzmahone
+1  A: 

You need to keep the plain-text user-names and passwords available for logging into external systems. You could try and encrypt this file yourself, and then obscure the key somehow in your application.

However, its likely your operating system (e.g. Windows) does offer ways of securing files and its likely that those are implemented by experienced experts - it's hard to recommend investing time in rolling your own!

So the best approach is to store your credentials as plain-text and rely on the operating system to protect the file e.g.

  • encrypted home directories where your web server runs as its own user so only it can get at its data
  • whole disk encryption

Consideration to how the machine / service 'logs on' at start-up will need to be given if this is meant to be unattended.

The question itself is covered in security disclaimers so this point does not need to be laboured.

  • It will keep out idle peers who get to a terminal on the server
  • It won't keep out dedicated attacker with access to the running machine and physical equipment (everything from firewire and usb devices to coolant attacks are basically impossible to defend against)
  • It won't stop these credentials being attacked in-flight between your server(s) and the other systems they are logging into - if its normal http logins to the other systems without even http-digest authentication...
Will