I have a web project where I need to store a username and password in an SQL database. the username/password are for exchange web services.(so it cannot be hashed, I need to be able retrieve a clear text password) Each user of the web page will have to enter their username and password once and this is the information I want to store in SQL database, but in a way so its not possible to decrypt it for others then the user logged in to the web application (due to security concerns) I was thinking I could do this by using the users password for the web application to encrypt and decrypt the password. In this way you can only decrypt the exchange password if you know the users password for the web application. (which is hashed for this web application)

The web application is using forms authentication and the users has the option to "Remember me" so they don't have to sign in every time and here is the problem. I might not get a request with password for every new session. The exchange servers are out of our control, so we cannot use any impersonation, add users with special permission to mailboxes etc. The only thing we know about the exchange server is what we get through the exchange autodiscover service.

The only way I can think of is to create a hash representation of the users password and store it the authentication cookie. Then I can use this hash (plus some salt) to encrypt and decrypt the password for the exchange web services.

Is this a safe way to do it? is there any better way to solve this issue?

  • If you are storing a hash of the password in your DB, why would you store an extra hash as a cookie? That is asking for problems.
    – Nzall
    Oct 23 '16 at 13:22
  • It will not be the same hash in the cookie and in the DB. if I use the hash in the DB to encrypt the password for exchange, then we have access to decrypt the exchange password without the user accept it. this should not be an option, that is why I was thinking of saving a hash of the password (pluss some salt) in the users auth cookie, so only the user has the key to decrypt the password and its not stored in our systems.
    – Mr Zach
    Oct 23 '16 at 15:57

Not sure if there is a better way, but this is how I would do it. I think it is similar to what you describe in the question.

  • Store the network credentials encrypted with a key that is derived from the users password, e.g. using PBKDF2). (If you also store password hashes for authentication, use a different salt so they are not identical.) That way, if your database is compromised the network credentials will still be relatively safe.
  • To make the network credentials available without password reentry, I would encrypt them with a random key and store the encrypted value (but not the key) in a separate table. The key I would send as a cookie (with appropriate time out) to the user. That way, if your database is compromised the network credentials are still safe because the key is not there.
  • Note that I would use a cryptographically secure random key, and not something related to the user, password or session ID.
  • Remove entries from the table as soon as the session times out or a user loggs out.

The backside of this is off course that a user that can steal the cookie can decrypt the network credentials. But this will be a problem for any system where password reendry is not required - someone who could steal the session cookie would be able to appear as logged in anyway. So I think that is a drawback with not requiering password reentry, and not with this particular solution.

Disclaimar: This is not my area of expertece so you might want a second opinion on this.

  • I ended up by saving a unique encryption key for each email account on the server. then I store the encrypted email password on the clients webstorage. Then I only submit the password when Its needed. So we do not have any copy of the password and the password cannot be decrypted on the client machine without the encryption key (which is never transferred to the client machine)
    – Mr Zach
    Oct 24 '16 at 20:44
  • Within the scope defined by the question, creating a key for the data derived from the users password (and not reversible) solves the problem. +1. Its a far better approach than using a random key in local storage which is tied to a specific device and difficult to reinstate.
    – symcbean
    Jan 22 '17 at 1:50

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.