How does RavenDB succeed in protecting your database both in transit and at rest?
With cybercrime estimated to have cost the global economy over one trillion USD in 2020, database security has never been more relevant.
To properly secure a database, data must be protected both in transit between server and node, and at rest on the server.
Encryption at rest protects the data stored on the server, preventing it from being viewed, stolen, or otherwise accessed by someone with malicious intent. If your disk is lost or stolen, for example, an attacker will have complete access to your data. When encrypted, however, the data will be unreadable and the attacker will see it only as random noise.
How RavenDB Handles Encryption at Rest
A common problem with database security is that it can become too complicated to understand and implement. As a result, it’s often put off, forgotten, or abandoned completely. RavenDB’s solution is to take care of security behind the scenes, requiring only a few clicks from the user on setup to completely secure the database. (Of course, as with most things in RavenDB, you have the option to get more hands-on if you wish.)
RavenDB uses an authenticated encryption scheme called XChaCha20Poly1305 with a 256-bit key. The details of XChaCha20Poly1305 are well beyond the scope of this article, but the important things to know are that it does its job extremely well, it has been thoroughly vetted by industry experts, and it is standardized by the IETF1.
Data is encrypted at the lowest possible layer – the storage layer – using RavenDBs own custom-made storage engine; Voron. Encryption at this layer is completely transparent to other levels of the server, meaning you never have to deal with its complexities.
Another advantage of performing encryption at this layer is that it’s much faster, which helps offset the inherent performance cost of encryption.
There wouldn’t be much point in having an encrypted database if it transferred data in an unencrypted form for the whole world to see. To avoid this misstep, RavenDB requires you to have authentication and HTTPS enabled to create an encrypted database. The good news is authentication and HTTPS are set up automatically when you select secure mode in the RavenDB setup wizard.
If you wish to set up authentication your own way you can do so by following the instructions available here.
Once in secure mode, you can create an encrypted database using the studio as shown in the image below, or manually using the REST API and Client API.
Yes, it’s as easy as it looks.
Note: You can’t enable encryption on an already existing database, it must be done upon creation. You can, however, export the database and then import the data into a new encrypted database.
After this step, you’ll be given your database key.
Keys In RavenDB
A key is a short, random-looking string that can be used to mathematically transform your data into an unrecognizable format and back.
When you create an encrypted database in the studio you’ll be given its key in text and as a printable QR code. It is very important to save it, otherwise you’ll never see it again.
Accessing the data on the RavenDB servers does not require the key – that’s subject to the access permissions of authenticated users. You do, however, need the key for crucial functions, such as restoring the database from a backup and moving data files between servers.
If you’re creating your database using the APIs you can find further information regarding the key here.
Key Management Is Really Important
You know how it feels when you lock yourself out of your house or car or hotel room? Well locking yourself out of your database is much worse.
The only way to translate the data in an encrypted database back to a readable format is if you know the encryption key. If you lose it you may never be able to access your data again. Ever.
RavenDB holds the key internally and will use it to store and retrieve data. However, if you need to restore from backup, rebuild the server or recover from a disaster, you’ll absolutely need the key.
The importance of keeping your key secure cannot be overstated, not just so you don’t lose it, but also to prevent others from obtaining it and gaining access to your database.
Keeping a physical copy of your key locked away in a very safe location is an easy and surprisingly secure method of storing your key. You can’t hack into a locked cabinet after all. This is why RavenDB gives you your key in the form of a printable QR code.
Each database in RavenDB has its own key, and all these database keys are encrypted by the server master key. This server master key is encrypted differently depending on your operating system. For Windows, it’s encrypted by DPAPI which is related to your windows password, while for Linux it’s handled by file system permissions. The end result is the same – ensuring only the user who created the database has access to the key.
You can also tell RavenDB to run a specified executable to fetch the server master key if you want to store and retrieve it by your own methods. This can be used to set up integration with HSMs, key vaults, or cloud-based key management systems.
Your data isn’t encrypted by the database key. Instead, it’s encrypted by derived keys generated from the database key. They’re created in such a way that they cannot be reverse-engineered to work out the database key, and having separate keys ensures that if an attacker does somehow figure out one key they can’t use it anywhere else.
Despite their importance, you’ll rarely need to actually use your keys. You’ll only need to bring them out for special occasions like restoring a database from a backup or if you want to add a node to a database using the same database key.
What’s Encrypted and What’s Not?
With encryption enabled, plaintext data is never written to disk. Data is only decrypted in memory during an active transaction, and even then, only the specific data needed for the transaction. When the OS runs out of memory, it may send in-memory data to disk, but that data will still be in encrypted form. After the transaction is completed, the associated memory is immediately wiped.
The exceptions to working with only encrypted data are special temporary buffers used for compression, recovery, and other such functions. These files are of necessity stored unencrypted in memory, however, they’re kept in locked regions of memory so that the OS won’t page them out to disk and data won’t leak. Locking data in memory can lead to failures if there isn’t enough physical RAM available for RavenDB to lock, so if RAM is limited you may wish to read more and find out how to change related settings here.
The server store is not encrypted by default. It contains server-wide information like database records and compare-exchange values. It also stores the database keys, though these are stored encrypted. You can enable server store encryption if necessary by following the instructions here.
To Encrypt or Not to Encrypt
With powerful and comprehensive encryption available with just a few clicks during setup, you might be tempted to enable it on every database you create. In most cases that is the right call. However, it’s worth remembering that security always comes at a cost.
In RavenDB the performance cost of encryption is only 15-20% for most typical scenarios, and some additional memory is used to hold temporarily decrypted data. These are small prices to pay to keep your data safe, so unless you’re absolutely certain you don’t need encryption it’s highly recommended that you turn it on.
There’s a lot to say about encryption at rest in RavenDB, and this article only scratches the surface. In the end, though, it’s really just as simple as a single click.