A simple way to encrypt and decrypt in Rails 5
I wanted a simple way to store few, two, encrypted strings in my local database. These strings come from the user form. Looking around I have found attr_encrypted but, sadly, I ran into too many issues. I needed something now and simple!
It appears that Rails has something called MessageEncryptor. Why haven’t I found this three days ago! Yes I have spent three days on a simple thing like this. This is one of the reasons I hate to use gems! If I have to recreate something that has already been created, damn right I will!
The work flow is, the user inputs their secret key, in a form, then submits to be saved. When saved, I would have an encrypted string saved in the database. If the application needs to use that string, such as for an API authentication, the app would decrypt the string.
Our user table will have the column name, in this example, consumer_key as string.
The User Model
In our rails console, we save these two values and an environment variable:
salt = SecureRandom.random_bytes(64) # Some value. Copy then save
key = ActiveSupport::KeyGenerator.new('password').generate_key(salt) # Some value. Copy then save
We store the values because we’ll need to reuse the key before we can decrypt.
I use the figaro gem to create an application.yml file to store my variables:
SALT: <the sting you have copied from your terminal>
KEY: <the sting you have copied from your terminal>
When your user has submitted the form, it will save an encrypted string for your “consumer_key” column. Now to decrypt:
# In your controller or model
crypt = ActiveSupport::MessageEncryptor.new(ENV['KEY'])
consumer_key = User.find(1).consumer_key
puts crypt.decrypt_and_verify(consumer_key) # Original value!
There you have it. Since I’m still new to Rails, I’m not sure if there is a potential flaw when storing the key used to generate the encryption and reuse elsewhere but it does what you want. If not, let me know!