6

I'm currently planning the development of a PHP application that shall require user passwords for external services to be stored so that they can be logged into simultaneously when the user logs into my application.

I shall need to store passwords in a secure, i.e. not plain text, and not base64 encoded but that shall also need to be accessible as plain text by the application, one way or another.

I've only been able to think of something like the following:

When a user adds their credentials for the external service to their account, they re-enter their password for my application and that (in an encrypted form) is used to 'encrypt' the password for the external service somehow, but in a way that makes it accessible still.

Does anyone have any thoughts on if this is possible, or a potential solution?

Thanks

Also: it's worth noting that it will be an SSL connection that the data is sent over.

Out of curiosity: Say for example; Google Mail, you can add email accounts to your Google Mail account so that all of them are checked. Does anyone have any thoughts on how Google store the passwords for the accounts you add?

Seer
  • 5,138
  • 5
  • 31
  • 52

7 Answers7

7

The problem with this in general, is if your system is every compromised, the attacker can get all the passwords for all the systems, because they are encrypted and not hashed. There is no way around this, since you want to be able to get the plain-text passwords.

If you must do this, you can use something well trusted like OpenSSL to encrypt the passwords.

Oleksi
  • 12,583
  • 4
  • 51
  • 76
3

From a securities stand point, you really should never store a password anywhere. I would have the user enter their password md5 their password and store that. So when he authenticates its authenticated vs the md5. As for the externals. You could take the external password and XOR the external password with the stored md5. That way you could undo it to pass it to the external source. Or the better way would be to ask for the password every time for the externals. This is a choice of risk vs convenience.

user1836293
  • 138
  • 6
  • The passwords for my application would be stored using (most likely) blowfish encryption. This could of course be checked against easily, which is the point I guess. The general idea of your answer is what I was thinking, somehow the user's password for my service being used to 'undo' the encryption of the password for the external service. – Seer Nov 21 '12 at 16:31
1

Well, you may encrypt the passwords by user's own password (not storing it anywhere), and just ask for it every time the communication is being made, this way the passwords are probably safe.

nothrow
  • 14,840
  • 6
  • 50
  • 97
  • By this do you mean, they would enter the password for my application, or the external service every time? – Seer Nov 21 '12 at 16:29
  • For your application. Their password for your application is the key used to encrypt/decrypt the external service's password. But if the user forgets their password, all the encrypted passwords will be lost. – Christian Nov 21 '12 at 16:29
  • Well, say there would be a 'forgotten your password' feature. This would mean all of the passwords for their external accounts would need to be re-entered, and then re-encrypted with the new password as the key, the same applies for if the user were to change their password I suppose. – Seer Nov 21 '12 at 16:34
  • 1
    If the user changes their password, you could just do a mass decryption on the old password & mass encryption on the new password. – Christian Nov 21 '12 at 16:35
  • Very true, that makes a lot more sense. – Seer Nov 21 '12 at 16:37
  • Let's say it is security feature.. If you forgot your password, you need to re-enter passwords for all of your accounts, (as 'retrieve password' may mean your account was compromised) – nothrow Nov 21 '12 at 17:30
1

GAH... I wish everyone would just standardise on keys:

<?php
$connection = ssh2_connect('shell.example.com', 22, array('hostkey'=>'ssh-rsa'));

$sth = $dbh->prepare('select keyLoc from auth where username = :user');
$sth->bind_param('user', 'username');
$key = $sth->fetch(PDO::FETCH_ASSOC);

if (ssh2_auth_pubkey_file($connection, 'username',
                      $key,
                      '/home/username/.ssh/id_rsa', 'secret')) {
  echo "Public Key Authentication Successful\n";
} else {
  die('Public Key Authentication Failed');
} 
?>

It would make life so much easier. Just copy your public key everywhere and keep your private key on you.

hd1
  • 30,506
  • 4
  • 69
  • 81
1

What you should do instead is to use Oauth - safer and also much more user friendly when it's implemented correctly.

Zend oauht client

Zdenek Machek
  • 1,652
  • 1
  • 20
  • 29
0

You can use php mcrypt, see relevant question here. Or if you prefer to encrypt/decrypt server side mySQL has a AES encrypt function.

Community
  • 1
  • 1
gSaenz
  • 633
  • 5
  • 21
0

You might use something like PKIF (specifically PKIFCRYPTO) and NSS or MS-CAPI. It's not for the faint of heart, but you'll want to demonstrate a certain degree of competence to the users who decide to trust you with their credentials.

jah
  • 1,917
  • 1
  • 17
  • 33