Before Rails 7, we used a lot of gems like attr_encrypted to encrypt and decrypt data in Active record models.
Let’s take an example of a
where we want to store the email in an encrypted format.
attr_encrypted gem we would do something like this:
This increases the dependency on third-party gem for critical functionality like encryption.
To handle this problem, Rails 7 adds encrypted attributes to ActiveRecord models.
- Firstly, we need to add some keys to our Rails credential file. Run the following command to generate the key set:
- Specify the attributes we need to encrypt. This happens at the model level:
The library will transparently encrypt
Deterministic and Non-Deterministic encryption
- By default, ActiveRecord Encryption uses a
non-deterministicapproach for encryption. That means encrypting the same email twice will result in 2 different ciphertexts. It is better for security purposes, but it makes querying the database impossible. So we can use the
deterministicapproach to resolve this issue.
After this if we query the model normally like:
Since we did not set
deterministic: true for the
the query fails to find the user.
Custom Encryption methods
Rails 7 uses the EncryptableRecord concern to perform encryption and decryption when saving and retrieving values from the database. The main components of an encryption system are:
- Encryptor - responsible for encrypting/decrypting data.
- Cipher - the encryption algorithm (Aes 256 GCM)
- KeyProvider - serves encryption and decryption keys
- MessageSerializer - in charge of serializing and deserializing encrypted Message.
These components can be customized according to the needs by modifying the respective settings in the config file like:
config.active_record.encryption.encryptor = MyEncryptor.new
For more details, refer to this pull request.