Custom Tag-based field encryption/decryption using GORM hooks-blog II of blog series

Impelsys Tech Blog
Impelsys
Published in
3 min readAug 30, 2022

by Abhilash Bhat

The wait is over, and here is the second blog of the two blog series. In case you have missed the first blog, refer to the following link:

The previous blog elaborated on the process of struct tag-based encryption in a project running on Golang. However, the encryption or decryption functionality was called every time it was required. This has scope for enhancement, and this blog demonstrates how the fields could be encrypted just by adding only struct tags and a few gorm hooks.

GORM is a developer-friendly, ORM library for Golang. It is very simple to understand and use.

Hooks are functions that are called before or after Create-Read-Update-Delete (CRUD) operation. If you have defined specified methods for a model, it will be called automatically when creating, updating, reading, or deleting, and if any call back returns an error, GORM will stop future operations and roll back the current transaction.

GORM provides a lot of hooks under the hood. Some of them could be found in the given link.

The following hooks have been used to achieve encryption and decryption dynamically.

BeforeCreate- Before creating a new row
AfterCreate- After creating a row
AfterFind- After finding an existing row
BeforeUpdate- Before updating an existing row
AfterUpdate- After updating an existing row

Now let’s go through the BeforeCreate and AfterCreate in the below example:

As shown in the above snippet, the BeforeCreate and AfterCreate hooks have been defined on the Customer struct. (Customer Struct is a struct whose fields will be persisted in the table).

After this, the encrypt functionality can be implemented in the BeforeCreate hook and decrypt functionality in the AfterCreate hook.

This way the fields get encrypted before getting inserted into the table and decrypted after insertion, for serving purposes. Below is a simple example of a function to insert a customer row into the table. Note that there is no additional code involved here to encrypt or decrypt the customer fields.

Above was an example of an insert scenario. Based on the use case (Read, Delete or Update) the right hooks can be selected and the encrypt-decrypt functionality can be implemented. In all these cases, the configuration needs to be done only once.

The major benefit of this approach is, that it is a one-time configuration setup. After this config, any GORM queries written using modeled struct will have the encryption and decryption functionalities implemented under the hood and no additional code needs to be written. This also reduces broiler plate code and ensures clean code is written.

The challenge with the above approach is that it works only if the query is written using the modeled struct. If any raw queries are written, then the encryption and decryption functionality will have to be called manually, as discussed in the first blog of the series.

Also, in the long run, whenever an encryption key changes, the fields need to be decrypted using the old key and re-encrypted using the new encryption key. An API can be exposed to achieve the same, and it could be invoked, whenever there is an encryption key change.

To conclude, based on the approaches mentioned, the process of encryption and decryption can be simplified using custom tag-based encryption. Meanwhile, this approach of encryption and decryption using GORM hooks helps in saving a lot of time and energy for the developer. Hope this article will help leverage the same in your projects. Please feel free to drop suggestions if any.

--

--

Impelsys Tech Blog
Impelsys

Impelsys is a global leader in delivering impactful, engaging & adaptable online learning solutions for global publishers, education providers, & enterprises.