Dentro de la materia de Seguridad, encontramos artefactos para implementar la encriptación mediante diferentes opciones (consultar la documentación oficial). Una de estas formas de encriptación la encontramos a nivel de columna, la cual podemos implementar a través de una extensión llamada pgcrypto. Para usar esta extensión, debemos crearla dentro de la base de datos en uso mediante el comando:
CREATE EXTENSION pgcrypto;
Ahora tenemos a nuestra disposición nuevas funciones para incorporar en el lenguaje SQL, a nivel de columna.
La primera función se llama PGP_SYM_ENCRYPT(), y permite encriptar un texto dado, mediante al algoritmo especificado. La siguiente sintaxis encripta mi nombre mediante el algoritmo AES-KEY:
PGP_SYM_ENCRYPT('Rafael','AES_KEY')
La segunda función se llama PGP_SYM_DECRYPT(), y desencripta la columna encriptada mediante el algoritmo especificado:
PGP_SYM_DECRYPT(nombre_columna::bytea, 'AES_KEY')
Ejemplo
Vamos a poner en práctica lo anterior. En primer lugar vamos a crear una tabla de usuarios, en donde almacenaremos los nombres de usuarios y su contraseña, la cual vamos a encriptar para evitar robo de contraseñas:
CREATE TABLE usuarios(nombre VARCHAR(50), password VARCHAR(255));
INSERT INTO usuarios (nombre, password) VALUES ('Rafael', PGP_SYM_ENCRYPT('mypassword','AES_KEY'));
Si se lista la información, veremos que la contraseña está encriptada:
SELECT nombre, password FROM usuarios;
Para ver los datos desencriptados, utilizaremos la siguiente sentencia:
SELECT nombre, pgp_sym_decrypt(password::bytea,'AES_KEY') FROM usuarios;
La siguiente sentencia cambia la contraseña, encriptando la misma:
UPDATE usuarios SET password=(PGP_SYM_ENCRYPT('newpassword', 'AES_KEY'));
Podemos hacer una búsqueda comparando el valor en plano con el valor desencriptado de la columna encriptada. En nuestro ejemplo, cuando hacemos un login, hemos de comparar el nombre y la contraseña. La siguiente sentencia resuelve el problema:
SELECT COUNT(*) AS coincidencias FROM usuarios WHERE nombre = 'Rafael' AND PGP_SYM_DECRYPT(password::bytea, 'AES_KEY') = 'newpassword';
Ver también
- PostgreSQL encryption options
- pgcrypto documentation
- Column Level Encryption With pgcrypto On PostgreSQL