Encryption at rest using EF
Encryption at rest can come in handy when we have some sensitive data that we need to store in our database and we don't want to store it in plain text for everyone to see.
In my case I needed to store some API keys in the database. The keys are inputted by the app users and the app later uses these keys for accessing some external services.
In this tutorial I will show you a seamless way to use encryption at rest in your .NET application using EF value converters.
How it will work
First we will create a ValueConverter that encrypts values on write and decrypts on read. We will also create an attribute, EncryptedAttribute, and apply the value converter to each of the properties that has the EncryptedAttribute.
The value converter class
We will need a string-string value converter that can encrypt on write and decrypt on read.
For this we will use AES encryption and we will need an encryption key. This key is a simple base64 string but we need to store it securely (in Azure Key Vault for example). I won't go in detail here, but we well also need a unique IV (initialization vector) key that will basically ensure that we always get different ciphers even if the input string is the same. Because the IV value is also needed when we decrypt the data we will just append the IV value to the cipher and store it in the database as part of the encrypted value.
Here is the source code of my value converter:
The Encrypted attribute
We will create an attribute and write some logic to apply the converter to the properties that use this attribute.
The source code for the attribute:
And here is the code that will apply the converter based on the attribute.
I will place this static method inside my converter:
And the final step is to call the EncryptedConverter.Apply function from the OnModelCreating method of our db context:
Ready to go
Now we just need to add the [Encrypted] attribute to the properties we want to store in an encrypted form. Your DbContext will work as usually, you can write and read your plain text properties but in the underlaying database table the data will be encrypted.
You can also find the source code and a working example in this repository: https://github.com/boros-csaba/encryption-at-rest-with-property-attribute
Comments available on dev.to