Encryption: Database Encryption

In RavenDB you can create encrypted databases. Each encrypted database will have its own secret key which is used to encrypt and decrypt data.

Creating An Encrypted Database Using The Studio

When creating an encrypted database using the Studio, you will receive a secret key which will allow you to recover the encrypted data in case of a disaster, and when restoring from backup. During normal operations there is no need to supply the secret key to RavenDB.
See Secret Key Management for more information.

Figure 1. Secret Key

Danger

Download, print, or copy and save the secret key in a safe place. It will NOT be available again!

Creating An Encrypted Database Using The REST API And The Client API

Before creating the database, a secret key must be generated. Generating and storing secret keys is restricted to Operator or ClusterAdmin Security Clearances. RavenDB uses a cryptographically secure pseudo-random number generator and it is recommended that you use it. If you must use your own secret key, please make sure it is 256 bits long and cryptographically secure.

You must use a client certificate to make the request because the server is using authentication.

Windows Example

Load the client certificate in PowerShell:

$cert = Get-PfxCertificate -FilePath C:\secrets\admin.client.certificate.example.pfx

Make sure to use TLS 1.2 (or 1.3):

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Ask RavenDB to generate a key for you:

$response = Invoke-WebRequest https://your-server-url/admin/secrets/generate -Certificate $cert

Then send the key to the RavenDB server on which the database will be created. Note that the database doesn't exist yet, but you will still need to supply its name. Make the following POST request to assign the secret key to a specific database:

$payload = [System.Text.Encoding]::ASCII.GetString($response.Content) 
Invoke-WebRequest https://your-server-url/admin/secrets?name=MyEncryptedDatabase -Certificate $cert -Method POST -Body $payload

Finally, create the encrypted database using the Client API:

store.Maintenance.Server.Send(new CreateDatabaseOperation(new DatabaseRecord("MyEncryptedDatabase")
{
    Encrypted = true
}));
await store.Maintenance.Server.SendAsync(new CreateDatabaseOperation(new DatabaseRecord("MyEncryptedDatabase")
{
    Encrypted = true
}));

Linux Example

When generating a client certificate using RavenDB, you will receive a Zip file containing an admin client certificate (.pfx, .crt, .key).

First we will create a .pem certificate file from the .crt and .key files:

cat admin.client.certificate.example.crt admin.client.certificate.example.key > clientCert.pem

Ask RavenDB to generate a key for you:

key=$(curl --cert clientCert.pem  https://your-server-url/admin/secrets/generate)

Then send the key to the RavenDB server on which the database will be created. Note that the database doesn't exist yet, but you will still need to supply its name. Make the following POST request to assign the secret key to a specific database:

curl -X POST -H "Content-Type: text/plain" --data $key --cert clientCert.pem https://your-server-url/admin/secrets?name=MyEncryptedDatabase

Finally, create the encrypted database using the Client API:

store.Maintenance.Server.Send(new CreateDatabaseOperation(new DatabaseRecord("MyEncryptedDatabase")
{
    Encrypted = true
}));
await store.Maintenance.Server.SendAsync(new CreateDatabaseOperation(new DatabaseRecord("MyEncryptedDatabase")
{
    Encrypted = true
}));

Remarks

Database encryption must be enabled when creating the database. If you wish to use encryption in an existing database, it must be exported and then imported back into a new encrypted database.

Indexing transaction size

Indexing is most efficient when it is performed in the largest transactions possible. However, using encryption is very memory intensive, and if memory runs out before the transaction completes, the entire transaction will fail. To avoid this, you can limit the size of indexing batches in encrypted databases using Indexing.Encrypted.TransactionSizeLimitInMb.