← Blog

Encrypt & Decrypt text in Ruby

If you want to pass some information to a client that you don’t want the client to read or tamper with, read on!

The usage of our TextEncryptor is straightforward:

data = { ... }
serialized_data = JSON.dump(data)
encoded_data = TextEncryptor.encrypt(serialized_data)

# ...

serialized_data = TextEncryptor.decrypt(encoded_data)
data = JSON.parse(serialized_data)

Implementation:

class TextEncryptor
  class << self
    def encrypt(text)
      text = text.to_s unless text.is_a? String

      len   = ActiveSupport::MessageEncryptor.key_len
      salt  = SecureRandom.hex len
      key   = ActiveSupport::KeyGenerator.new(secret).generate_key salt, len
      crypt = ActiveSupport::MessageEncryptor.new key
      encrypted_data = crypt.encrypt_and_sign text
      "#{salt}$$#{encrypted_data}"
    end

    def decrypt(text)
      salt, data = text.split "$$"

      len   = ActiveSupport::MessageEncryptor.key_len
      key   = ActiveSupport::KeyGenerator.new(secret).generate_key salt, len
      crypt = ActiveSupport::MessageEncryptor.new key
      crypt.decrypt_and_verify data
    end

    private

    def secret
      Rails.application.secrets.secret_key_base
    end
  end
end

One of the ways I use this is to store a proof that a phone number is verified on client side and allow exchanging that encoded phone number token to login or signup. You can read more about this in one of the following blog posts.

Thank you for reading!