In the last blog post of this series, we discussed in detail how Master Key encryption works. In this post, based on what we already know about Master Key encryption, we look into how Master Key rotation works.
The idea behind Master Key rotation is that we want to generate a new Master Key and use this new Master Key to re-encrypt the tablespace key (stored in tablespace’s header).
Let’s remind ourselves what a Master Key encryption header looks like (it is located in tablespace’s header):
From the previous blog post, we know that when a server starts it goes through all encrypted tablespaces’ encryption headers. During that, it remembers the highest KEY ID it read from all the encrypted tablespaces. For instance, if we have three tables with KEY_ID = 3 and one table with KEY ID = 4, it means that the highest key ID we found in the server is 4. Let’s call this highest KEY ID – MAX KEY ID.
How Master Key Rotation Works, Step by Step:
1. User issues ALTER INNODB MASTER KEY;
2. The server asks keyring to generate a new Master Key with server’s UUID and KEY_ID being MAX KEY ID incremented by one. So we get INNODB_KEY-UUID-(MAX_KEY_ID+1). On successful Master Key generation, the MAX KEY ID is incremented by one (i.e. MAX_KEY_ID = MAX_KEY_ID + 1).
3. The server goes through all the Master Key encrypted tablespaces in the server and for each tablespace:
– encrypts tablespace key with the new Master Key
– updates key id to the new MAX KEY ID
– if UUID is different than the server’s UUID it gets set to the server’s UUID
As we know, the Master Key ID used to decrypt table is built of UUID and KEY ID read from the tablespace’s header. What we are doing now is updating this information in the tablespace’s encryption header, so the server would retrieve the correct Master Key when trying to decrypt the tablespace.
If we happen to have tablespaces coming from different places – like, for instance, retrieved from different backups – those tablespaces may be using different Master Keys. All those Master Keys would need to be retrieved from keyring on server startup. This might make the server’s startup slow, especially if we are using server-based keyring. With Master Key rotation, we re-encrypt tablespace keys with one – the same for all tablespaces – Master Key. Now the server needs to retrieve only one Master Key from Key server (for server-based keyring) on startup.
This is, of course, only a nice side effect – the main purpose why we do Master Key rotation is to make our server more secure. In case Master Key was somehow stolen from the keyring (for instance, from Vault Server) we can generate a new Master Key and re-encrypt the tablespaces keys, making the stolen key no longer valid. We are safe … almost.
In the previous blog post, I explained that once a decrypted tablespace key is stolen, a third-party can keep using it to decrypt our data – given that they have access to our disk. In case Master Key was stolen, and if the third-party had access to our encrypted data, they could use the stolen Master Key to decrypt the tablespace key and thus be able to decrypt the data. As we can see, Master Key rotation will not help us in that case. We will re-encrypt the tablespace key with the new Master Key, but the actual tablespace key used to encrypt/decrypt tablespace will remain the same; so “a hacker” can keep using it to decrypt the data. I previously hinted that Percona Server for MySQL has a way of doing actual re-encryption of tablespaces instead of just re-encrypting tablespace key. The feature is called encryption threads, however, at this point in time, it is still an experimental feature.
A case where Master Key rotation is helpful is when Master Key is stolen, but the attacker did not have a chance to use it and decrypt our tablespace keys.