8

I'm making an application in PHP and there is a requirement that it must be possible to decrypt the passwords in order to avoid problems in the future with switching user database to different system. Consider that it's not possible to modify this future system's password method and I need plain text passwords in order to have the passwords generated.

The plan is to encrypt the user's password with a public key that is stored on the server. Authentication is done by encrypting the input and comparing the results. There is NO decryption done. The private key capable of the decryption is stored off-site for later usage.

What encryption/decryption algorithm would you suggest? Are the encrypted passwords still as safe as hashing (MD5/SHA1) when you consider the private key is not available to the attacker?

Jammer
  • 97
  • 1
  • 4
  • 8
    MD5 and SHA1 are not encryption, but hashing. Are you talking about encryption or hashing here? – Matti Virkkunen Mar 31 '10 at 19:53
  • What kind of "private key" do you talking about in the context of hashing? Did you mean GPG/PGP? – erenon Mar 31 '10 at 19:55
  • Why would using a hash have an adverse effect on moving to a different system? – LizB Mar 31 '10 at 19:56
  • 4
    @Matti Virkkunen and erenon: The question is "Are the passwords still _as safe as_ MD5/SHA1" ...when a decryptable password is stored but the private key is stored somewhere else (completely inaccessible for the webserver?) – VolkerK Mar 31 '10 at 20:00
  • How and where would you generate the encrypted versions of the password? Would it be a completely separated process (on a separate machine)? Or would the users generate it and submit both the encrypted password and their public key? Or ...? – VolkerK Mar 31 '10 at 20:07
  • 1
    @VolkerK I have no idea why you would want to use asymmetric cryptography for password storage. This is a violation of CWE-257. – rook Mar 31 '10 at 20:17
  • I'm talking about having an encryption instead of hashing in order to have myself access to the plain text passwords for future transportation into new system, which I do not want to modify to support any old password scheme! The encryption and storage would be done in the web server and all authentication would be done through encryption. The decryption is left there in order to one day have the plain text password available. I understand that this is not something that this might not be "preferable" approach, but if you consider the private key can't be stolen... what are the risks? – Jammer Mar 31 '10 at 20:37
  • @Jammer that is a violation of CWE-257. – rook Mar 31 '10 at 20:39
  • The risk is that if someone gets your database, they can probably get your private key too, and then they have all of your passwords with no extra work.. – Brendan Long Mar 31 '10 at 20:46
  • @Brendan The thing is they won't have access to the private key because it's stored on USB Drive and won't be used until I switch to different system. – Jammer Mar 31 '10 at 20:48
  • 1
    If the server get's access to the key (which it needs to verify the passwords), then anybody else *can* get access as well. – poke Mar 31 '10 at 20:49
  • @Jammer: And that's why I wanted to know how, where and when you plan to create the encrypted passwords. You would need the private key for that, wouldn't you? And another question: "Who came up with that requirement?", i.e. whom do "we" have to convince otherwise (and what kind of arguments are more likely to be convincing)? – VolkerK Mar 31 '10 at 20:51
  • @VolkerK @poke Maybe I should have clarified I'm looking for public/private encryption solution where the encryption is done with public key and decryption with private key. The server would only contain the public key and the authentication done against the encrypted value. – Jammer Mar 31 '10 at 20:54
  • Ok, which one the public and which one the private key is doesn't really matter. Somehow at some time you would have to store the encrypted password for the first time. What would the scenario be for a new user? I.e. are we "only" talking about "CWE-257" or are there other issues as well? (and just for the record: I'm against storing reversible passwords as well. It's all about whether there are also other issues that make this a rather pointless undertaking. Because up until now we seemingly haven't convinced Jammer yet) – VolkerK Mar 31 '10 at 20:58
  • @VolkerK New user registers to the site, the site encrypts his password with key A and stores it to database. When user logins to the site the password is again encrypted with key A and compared against the stored value. The key B (the decryption key) is used when the web systems are changed so it will be stored in a safe until that time. – Jammer Mar 31 '10 at 21:06
  • 2
    "If you need to change the password storage system, then you can update the password hash when the user logs in next." – rook Mar 31 '10 at 21:10
  • @Jammer Use message digest function, its the only secure password storage method. – rook Mar 31 '10 at 21:30
  • AFAIK MD5 and SHA1 hashing functions work on every system same, so switching to another DB isn't reason to use something different. – Petr Peller Apr 02 '10 at 08:04
  • Make an algorithm to decrypt the password or you can make it hashed in database at the time of insertion – aaditya Feb 16 '18 at 11:46

5 Answers5

8

I'll rephrase Jammer's approach -

  1. Generate a public/private key pair. Hard-code the public key on your webserver. Store the private key in a physical bank locker, outside the reach of webserver/database/any developer.
  2. When user registers, encrypt password + salt using public key. This step is identical to using a hash algorithm. Store the encrypted password + salt in the database.
  3. When you want to verify the password, encrypt it again, and compare it to the value stored in the database.

If an attacker gets the database, he can't decrypt the passwords because he doesn't have the private key. He cannot get the private key because it is in a bank vault outside his reach. Two identical passwords will still be stored differently in the database because of the salt.

I don't recommend using the above approach because at any point of time in the future someone could abuse the private key and get access to all passwords.

But if you guarantee that the private key will always remain private, then I don't see a technical flaw.

I could be wrong, of course.

Sripathi Krishnan
  • 30,948
  • 4
  • 76
  • 83
  • Its also rather expensive in terms of processing compared with just hashing the password. – symcbean Apr 01 '10 at 09:30
  • @Sripathi Correct, but what algorithm should I use? – Jammer Apr 01 '10 at 16:16
  • 1
    @symcbean it might be more expensive, but I recon this won't be a problem. Plus any attacker will have to spend so much more time when performing dictionary attacks against the database. – Jammer Apr 01 '10 at 16:18
  • 1
    Indeed, the reason bcrypt is suggested for hashing passwords is because it is designed to be slow. – Douglas Leeder Apr 02 '10 at 07:42
  • @Jammer - you should read the discussion in this thread - http://stackoverflow.com/questions/2283937/how-should-i-ethically-approach-user-password-storage-for-later-plaintext-retriev. Its a long discussion, but very pertinent to your question. – Sripathi Krishnan Apr 02 '10 at 19:33
5

Don't decrypt the password. If you need to change the password system in the future, add a field called storage_type (or whatever).

Then, when you need to change the passwords, you will check if it's an old password. If it is, next time they login, you can change the password encoding. Otherwise, login with the new system.

Macha
  • 14,366
  • 14
  • 57
  • 69
2

Being able to decrypt the passwords is a bad idea (and there's probably not any way of doing it that would be much better than storing them unencrypted). It sounds like your main problem is being able to use the passwords if you change your storage method. Just do what Linux does, store how you're hashing the password with the password. So for example $1$salt$hash is MD5. That way, if you decide to change how passwords are stored, you can still check against the old passwords (and if someone logs in correctly, you can update their password with the new hash).

Brendan Long
  • 53,280
  • 21
  • 146
  • 188
  • This would require me to modify the future platform, which I rather not do. Granted it will require some effort to move the plain passwords there too, but at least it won't require any administrative effort after the one time move. – Jammer Mar 31 '10 at 20:36
  • Couldn't you use something that you know will be supported in the future? For example, SHA512 is easy to do on pretty much any platform (if you can find a library to do encryption, you can probably do sha512 too). – Brendan Long Mar 31 '10 at 20:40
  • 1
    I agree, you shouldn't sacrifice security just to make it easier to switch to the *next* encryption method. Just start with a good one in the beginning, and you don't need to care much about any future changes. – poke Mar 31 '10 at 20:43
1

The only problem I see is that most public-private key encryption code out there will encrypt a symmetric key using the public key, and rely on the private key decrypting that, then use the symmetric key to encrypt the message.

You want to use the public key to directly encrypt the password+salt.

So attacks against your system boil down to:

  1. Attacks against general public/private key encryption
  2. Attacks against your private key store.
Douglas Leeder
  • 52,368
  • 9
  • 94
  • 137
-1

For most applications it is more than sufficient to store SHA-1 hashes of passwords.

Yes, there are known collisions in most hashing algorithms, but that doesn't imply an actual attack vector. Especially when you're salting the hashes.

For your salt: Store it in a configuration file that is not accessible from the outside but can be read by your PHP installation.

selfawaresoup
  • 15,473
  • 7
  • 36
  • 47
  • -1 What you are proposing is a recognized vulnerability. I'll see you on BugTraq. – rook Mar 31 '10 at 20:40
  • I'm looking for encryption solution, not hashing. – Jammer Mar 31 '10 at 20:44
  • 1
    Storing a single salt is only slightly better than not using one, using a salt for each password is a better idea. – Brendan Long Mar 31 '10 at 20:44
  • 1
    It all depends on how much security you actually need. As I said: For most applications, simple salted hashes will be sufficient. Many applications sadly are also so full with their own security issues that a less-than-perfect hash algorithm is the least of their problems . – selfawaresoup Apr 01 '10 at 06:31