Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to work with key rotation? #26

Open
SimonLab opened this issue Nov 29, 2019 · 1 comment
Open

How to work with key rotation? #26

SimonLab opened this issue Nov 29, 2019 · 1 comment
Labels
discuss question Further information is requested

Comments

@SimonLab
Copy link
Member

SimonLab commented Nov 29, 2019

Key rotation is mentioned on the Readme on the following parts in the Readme:

https://github.com/dwyl/phoenix-ecto-encryption-example#owasp-cryptographic-rules
image

https://github.com/dwyl/phoenix-ecto-encryption-example#1-create-the-encryption-app
image

and on the get_key function description:
https://github.com/dwyl/phoenix-ecto-encryption-example#3-define-the-6-functions
image

However it wasn't clear for me how to use key rotation (when to select a new key?, when to create a new key?, can we delete unused key?...). Maybe we can update the Readme to explain how rotation could be used in a project.

My first thought was to randomly get the index of the key from the list of keys and use this key each time we want to insert in the database an encrypted item. However randomising each encrypted item seems more to be the responsibility of the Initialization Vector (see #8).

So I think it's ok to use the same key for consecutive inserted items on a "long period" of time. We need then to create a new key (every 6 months or a 1 year?) to be used to encrypt the new inserted items and the old keys are only used to decrypt the previous items.

So we want to

  • Create a new key every 6 months or a year
  • Add the new key at the end of the key list (saved in environment variable) eg, "key1,key2,newKey"
  • The get_key/0 function will always get the last key of the list (ie the latest key created) to encrypt the data
  • When data is encrypted we want to save the current index of the key used, to be able to decrypt the data later on. Here the get_key/1 function can take the key index parameter to retrieve the correct key used on encryption.

@nelsonic is this logic correct or do you have other details or step in mind?

@SimonLab SimonLab added discuss question Further information is requested labels Nov 29, 2019
@nelsonic
Copy link
Member

Hi @SimonLab! Thank you for opening this question to seek clarification on Encryption Key Rotation.

Key rotation is designed to minimise the amount of data that can be decrypted in the event of a data breach.
A really good guide to this is: https://cloud.google.com/kms/docs/key-rotation
If an attacker were to gain access to the Database e.g through an SQL injection or other vulnerability,
the data is encrypted at rest with many different keys which multiplies the effort required to "crack" it.

The current consensus in the security community is that it's not practical to crack AES using current technology (_it would take all the computing power on earth more than the age of the universe to brute force 256-bit key ... so technically using one encryption key is the same as using many; if an attacker were able to crack AES it would not really matter because the whole system would be cracked. But due to the nature of how AES works, cracking one key does not give the attacker all the keys so using multiple keys is though to be more secure (in theory...). The way I think of encryption cracking is: that if anyone is ever able to build a Quantum Computer capable of cracking today's 256-bit key encrypted data, the entire tech-dependent world will fall apart and our data won't matter. A quantum computer in the future will break all encryption. 🙄

OWASP suggests that "Keys used for encryption must be rotated at least annually"
This is the bare minimum and helps mitigate the loss/compromise of a single encryption key.
However depending on your level of paranoia, annual key rotation is not nearly enough.

When to select/create a new key? > New keys should be created based on a pre-defined rotation frequency e.g: Yearly, Monthly, Weekly, Daily or even a new key per session in the case of "Perfect Forward Secrecy". https://www.wired.com/2016/11/what-is-perfect-forward-secrecy

In our case we don't need to rotate the keys while we are building the MVP.
But once we ship to production and have other people using the App
we will define a key rotation frequency based on our compliance needs.
By having a 4 byte key_id we can have a maximum of 9999 keys.
If we had a script to automatically create a new encryption key each day,
the 4 byte length would las us 27 years.
But the short answer is: we only need to have a basic get_key/0 function for MVP which sources the key(s) from an Environment Variable. Next we will use an existing system like AWS KMS or GCP KMS.
And then further down the line we will implement a more robust and 100% automated key management system (KMS) based on something like: https://github.com/tendermint/kms
The point is: we don't need to think about key rotation during MVP, we just need to have a get_key/0 function that we can later refactor 100% transparently to the users.

For anyone reading this in the future, the relevant reading is:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discuss question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants