Encriptando datos en Ruby on Rails 7 con Active Record Encryption

En este artículo veremos cómo encriptar datos a nivel de aplicación con Active Record Encryption, una de las features incorporadas en Rails 7.

Active Record Encryption sirve para proteger información sensible en nuestra aplicación, como datos de identificación personal de nuestros usuarios. Ejemplos comunes de datos sensibles podrían ser el número de pasaporte, la licencia de conducir, el número de seguridad social, etc.

Lo bueno es que Active Record Encryption hace que la encriptación sea transparente al cifrar atributos antes de persistirlos en nuestra db y descifrarlos al recuperarlos. Así, nuestra aplicación manejará los datos como si no estuvieran encriptados, pero ennuestra base de datos sí se guardarán encriptados. Ahora bien, suponiendo que ya cifraras tu base de datos, ¿por qué querríamos sumar cifrado a nivel de aplicación?

Hay varias razones, pero las principales son:

  1. El cifrado de datos sensibles agrega una capa adicional de seguridad. Con esto, no importa si un intruso accede a tu base de datos, a un backup o a los logs de tu aplicación, ya no podrá descifrar la información.
  2. El cifrado evita que los desarrolladores expongamos datos sensibles de los usuarios en los registros de la aplicación de forma involuntaria.

Y algo igual de importante, al utilizar Active Record Encryption, estamos definiendo reglas a nivel código, al dejar claro para todos lo que constituye información sensible en nuestra aplicación. Esto es muy útil cuando trabajamos en equipo porque estamos generando procesos o convenciones.

¿Cómo funciona?

Para usar esta característica, debemos configurar las claves de encriptación key_derivation_saltprimary_key y deterministic_key en nuestro archivo de credenciales (que se abre con el comando rails credentials:edit).

Para crearlas, podemos ejecutar el siguiente comando en nuestra consola:

bin/rails db:encryption:init

# Eso nos retornará claves-valor como las siguientes, que copiaremos y
# pegaremos dentro de nuestro archivo de credenciales

active_record_encryption:
primary_key: una_primary_key
deterministic_key: una_deterministic_key
key_derivation_salt: una_key_derivation_salt

Una vez que tenemos dichas claves, podemos utilizar la encriptación de atributos a nivel aplicación. Veamos un ejemplo habilitando el cifrado en el atributo driver_license del modelo User:

# app/models/user.rb

class User < ApplicationRecord
encrypts :driver_license
end

Con esto, cada vez que creamos un usuario, veremos el valor cifrado de driver_license en la tabla, pero mantendremos el valor sin cifrar cuando hacemos una consulta utilizando ActiveRecord.

Esto se ve claramente si miramos la consola de Rails al crear un usuario y al recuperarlo de la base de datos:

# rails console
>> User.create name: "Fabian Show", driver_license: "890AC9921"
TRANSACTION (0.1ms) begin transaction
User Create (0.4ms) INSERT INTO "users" ("name", "driver_license") VALUES (?, ?) [["name", "Fabian Show"], ["driver_license", "{\"p\":\"aOKC5WCsykZ=\",\"h\":{\"iv\":\"aLlEyI5LopPb0gxQ\",\"at\":\"R50hGkso0XbI9d9Lo-p+lq==\"}}"]]
TRANSACTION (1.2ms) commit transaction

>> User.last
=> #<User id: 1, name: "Fabian Show", driver_license: "890AC9921", ...>

Todo esto es posible porque Rails 7 utiliza el concern EncryptableRecord para encriptar y desencriptar al guardar o recuperar valores de la base de datos. Si te interesa leer más de Active Record Encryption, te sugerimos chusmear la documentación oficial.