En esta ocasión voy a explicar como realizar la encriptación de alguna columna de nuestra BD, esto con la finalidad de tener nuestros datos protegidos en caso de que se llegue a exponer nuestra información.
En mi caso utilice las siguientes versiones de los programas requeridos:
- PostgreSQL 13
- JDK 8
- Spring boot 2
Lo primero que debemos hacer es crear la extensión PGCRYPTO, para ello ejecutamos el siguiente código en nuestro manejador de base de datos (PGAdmin en mi caso):
CREATE EXTENSION pgcrypto;
Una vez creada nuestra extensión, debemos encriptar los datos existentes de nuestra(s) columna(s), para ello debemos elegir una contraseña segura (que contenga números, minúsculas, mayúsculas y caracteres especiales), si quieren pueden generarla desde este enlace, la contraseña no debe contener el carácter ‘?’ ya que al utilizarla en JPA nos va a marcar errores porque lo va a considerar como un comodín para un parámetro (esto me causo muchos dolores de cabeza).
Para realizar la encriptación de nuestras columnas ejecutamos el siguiente código:
UPDATE schema.table
SET column = PGP_SYM_ENCRYPT(column, ‘password’);
No es necesario agregar la clausula WHERE ya que debemos encriptar toda la columna sin discriminar datos.
Ya que tenemos encriptados nuestros datos, es tiempo de modificar nuestro código Java, en especifico nuestras entidades. En nuestras clases Java donde estan mapeadas nuestras tablas debemos agregar la siguiente anotación:
@ColumnTransformer(
read = "PGP_SYM_DECRYPT(column_name::bytea, 'password')",
write = "PGP_SYM_ENCRYPT(?, 'password')"
)
En este punto es donde nos causara un conflicto si nuestra contraseña contiene un ‘?’, ya que lo tomara como que le enviaremos un parametro. También es necesario colocar el nombre de la columna como se encuentra en nuestra BD, ya que si ponemos el nombre de la propiedad no lo reconocera.
Otra cosa importante es realizar la conversión de la columna a un bytea, ya que la encriptación se maneja mediante un arreglo de bytes, si no agregamos la conversión nos mandará un error al intentar desencriptar la información.
Con todo lo anterior nuestro aplicación ya debería estar funcionando sin problemas y la encriptación será transparente para nuestros usuarios, ya que ese proceso lo maneja JPA.
Nota: Si se estan ejecutando consultas nativas, para realizar la conversión es necesario agregar ‘::::’ para que los tome como un parseo, de lo contrario lo va a interpretar como un parametro SQL.