I'm in need of a safe way to store a password in a database, but I also need a way to get the original password back. Of course if this was not the case I would just hash it. To work around this problem I came up with the following solution, but I would like to know if its secure.

I have a secret key on the server, and another secret key that is saved in the client-side application. The latter is different for every user and a new key is generated every time a user logs in.

The only time the server will have both keys is when a user makes a request and the server needs to get the raw password. This means that when the server is breached the passwords are still secure, since you only have half of the total key, and since I'm using AES 256, you still need to crack 128bits.

Is this OK or am I missing something important?

Edit: I need to use the client's password in API calls to external services

  • 2
    So if the user's hard drive crashes, they lose access to their account? – Ajedi32 Sep 14 '16 at 13:28
  • @Ajedi32 No, I verify the passwords with an API. – Nathan Sep 14 '16 at 13:32
  • But you need the client-side key for that, right? (To decrypt the stored password and verify it matches what the user sent.) And the user's hard drive crashed, so they don't have that key anymore, and you're not storing it server-side for security reasons so... – Ajedi32 Sep 14 '16 at 13:33
  • 1
    No, I use the API of my client, which does have the hashed passwords. – Nathan Sep 14 '16 at 13:38
  • 1
    You mean the API of your server? If the hash check is occurring on the client, then anyone could log in to any account by tampering with the client-side code. Plus, if the hash is stored client-side that information would also be lost when the user's hard drive crashes. If you meant the hash is stored and checked server-side though, then yeah that makes sense. – Ajedi32 Sep 14 '16 at 13:43

Couple of Attack scenarios i think of

  1. First, If the server is compromised, then the attacker can silently wait(monitor) in the server to collect user side secret key as the requests come in. He can use this client key and the server key to recover plain text passwords.
  2. Second, If the server is compromised the attacker can use various other methods like client-side software updates and push malware to clients which will collect the client secret keys and send them to attacker.The attacker can have the dump of database and use these collected keys to decrypt the dump.

In any of above case, If the server is compromised, the attacker can gain access to plain text passwords.

  • 1
    Isn't scenario 1 possible with hashed passwords too? Compromise the server then wait for users to log in? – Ajedi32 Sep 14 '16 at 13:35
  • 1
    Number 1 will work no matter what, if the passwords are hashed server side you can still listen for the passwords before the hash function. Number 2 won't work since the server doesn't push the updates, and if you do have access to a update server and you can update the clients, you can just send the passwords to your own server. – Nathan Sep 14 '16 at 13:35
  • 1
    @DavidWestern Actually, scenario 1 could be prevented by using asymmetric keys, as in SSH. If the client never sends any sort of key to the server, the server can't steal that key. – Ajedi32 Sep 14 '16 at 13:39
  • @Ajedi32 Nice thought.scenario 1 can be prevented. DavidWestern, Number 2 is just a sample thought from social Engineering point of view. – Sravan Sep 14 '16 at 13:41
  • 1
    @DavidWestern that's the point, you prevent scenario 1 by not using a Username-Password system, you use public-key cryptography instead. You could still call it "Username-Password", by locally storing a private key (needed for authentication using the public key) and authenticate (under the hood) using username + public key. – SEJPM Sep 14 '16 at 15:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.