databaseencryptionpasswordscryptographypassword-storage

Securely storing credentials that can't be encrypted


I have a client that's running an aggregator of information from multiple accounts. The database needs to store usernames and password to other websites in a way that can be used later by a script to log into those websites to retrieve data.

Rather than store them as plain text, I'm thinking we can hash them for storage. Obviously, someone could still access the plain text version if they had access to both the code and the database, but not if they only had one or the other.

Any better ideas?


Solution

  • If your system asks the user for a password, you can use that password to generate a key to encrypt/decrypt the passwords for the other websites.

    With that, you require your user entering that password to be able to decrypt the passwords you have stored on your database.

    A more detailed flow here:

    1. User enters password "123456" when login into your system.
    2. You use the SHA256 of the "123456" password and get a key: "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92"
    3. Use that "8d969..." key to decrypt with AES the passwords of the sites in your database.

    You can refine this in a number of ways. For instance: salting the password before computing the SHA hash.

    As a practical sample on such salting, Michael suggest using PBKDF2 (with HMACāˆ’SHA-256 as its two parameters pseudo random function).

    Other enhancement: storing an encrypted version of the key to allow your user to change its own password without having to re-encrypt all his passwords... etc...