How to securely store the credentials?




Introduction:

I am sure every developer has encountered this question ‘How to securely store the credentials?’ The credentials (username and password) can be for many things like network share, emails, database etc which needs to be saved in configuration files. Credentials for user authentication mechanism also needs to be stored securely in database. There are multiple solutions for securing the credentials of users in database. But it is a challenge to store the credentials in configuration files as they cannot be saved in plain text. The credentials need to be secured while in transit as well. And if we want to get back the plain text credentials then how should the credentials be saved? This article explains a method of securely storing & transiting the credentials and retrieving them when needed.

Hashing as an option:

One of the methods to store the credentials in database for User authentication is to hash the credentials and save this data in database. When you have to authenticate the user, you compare the hash of credentials entered against the saved hashed value in database. You are just comparing the hash values. This method is used when you don’t want to retrieve the plain text credentials. But there are situations in which it may not be so simple e.g. how to store the credentials which are used to authenticate to database? Or if your system uses mailing service then where to save the email id and password? Usually, all such configurations are saved in a configuration file. But if the code gets exposed then the credentials saved in them are visible to everyone.

Securely storing the secrets:

Storing the secrets in a secret management tool is one of the solutions. There are multiple secret management tools in market like Hashicorp Vault, AWS Secret Manager, Cloud KMS, Confidant etc. Communication to these tools will usually be through APIs. There will be keys to authenticate to the secret management tool like Vault. In the configuration files we have to save these keys. Using secret management tool, we can avoid storing the database credentials in plaintext in configuration files.

Scenarios where hashing is not enough:

From above we come to know that to authenticate a user, credentials are stored using hashing in database. To avoid saving credentials in plaintext in config files, Vault like secret management system is used. But what if you want to get the decrypted credentials and use them? The credentials saved in database cannot be decrypted to plain text. We must save the credentials in database in such a way that it can be decrypted. But the encryption should be strong enough so that nobody else should be able to decrypt the password easily. So we have come up with a solution using both Vault and encryption techniques.

Using both Vault and Encryption:

Explained below is a solution using both Hashicorp Vault and encryption methodologies.



Steps in securely storing the credentials -

  • Administrator of web client creates new user by entering username and password.
  • This data is passed on to API service (through https).
  • A Master key is retrieved from the Vault storage.
  • A Private key is created with hash of this Master key.
  • Initialization vector (IV) of randombytes is created.
  • The credential text is encrypted with private key and IV.
  • The encrypted credential is concatenated with IV (as its random bytes, its again needed for decryption).
  • This concatenated encrypted credential is converted to base64 encoding.
  • Finally save this value in database.

When the data is in transit it will be the base 64 encoded encrypted credential. So the data is safe guarded while in transit. All the transactions between client and servers should be through HTTPS.

Below diagram gives the overall picture –



Decryption:

When the plain text credentials are needed, below steps needs to be done –

  • Retrieve the entry from the database.
  • Decode the base64 encrypted value.
  • Separate out the initialization vector (IV) and encrypted credential.
  • Fetch the Masterkey from Vault.
  • Generate the same private key using the hash of master key.
  • Using the private key and IV decrypt the encrypted credential.

Conclusion

In this method the credentials are not saved in plain text in configuration files. Credentials are not simple hashed values in database. A master key is saved in Vault which is used to create a private key using hashing. This hashed private key and random bytes are used to create encrypted credentials. While storing in database this encrypted credential is saved in base64 encoded form. So the credentials which are entered by user in front end are never visible in plain text anywhere. The hashing with private key, random bytes make the encryption strong and difficult to break.

All the data in transit should be through SSL protocol. Apart from above all the security best practices should be followed to safe guard the credentials.