Salta el contingut
 

Encriptació

Joan Puigcerver Ibáñez

Llicència: CC BY-NC-SA 4.0

(Reconeixement - NoComercial - CompartirIgual) 🅭

Introducció

La seguretat de la informació és un component essencial de l'administració de bases de dades. PostgreSQL proporciona diversos mecanismes per garantir la confidencialitat, la integritat i la protecció del contingut emmagatzemat.

En aquests apunts es detallen els conceptes, els components i els procediments principals relacionats amb l'encriptació en PostgreSQL.

Tipus d'encriptació en PostgreSQL

L'encriptació es pot aplicar en dos àmbits, segons on es troben les dades que es volen protegir:

  • Encriptació en repòs (at-rest): protegeix les dades quan estan emmagatzemades en disc.
  • Encriptació en trànsit (in-transit): protegeix les dades durant la transmissió per la xarxa, mitjançant connexions TLS/SSL.

PostgreSQL no incorpora de sèrie un mecanisme de xifratge transparent de dades (TDE).

Per xifrar totes les dades del clúster de manera transparent, cal recórrer a:

  • Xifratge a nivell de sistema de fitxers o de disc, extern a PostgreSQL, com LUKS a Linux o BitLocker a Windows.
  • Distribucions empresarials que sí que incorporen TDE, com EDB Postgres Advanced Server.

En canvi, la versió de la comunitat ofereix xifratge a nivell de columna mitjançant l'extensió pgcrypto.

Documentació oficial: Encryption Options – PostgreSQL

Encriptació de columnes amb pgcrypto

pgcrypto és una extensió que proporciona funcions criptogràfiques per encriptar i desencriptar informació a nivell de columna. Cal habilitar-la una vegada en cada base de dades:

CREATE EXTENSION IF NOT EXISTS pgcrypto;

Documentació oficial: pgcrypto – PostgreSQL

Xifratge simètric (pgp_sym_encrypt i pgp_sym_decrypt)

Les funcions pgp_sym_encrypt i pgp_sym_decrypt xifren i desxifren text mitjançant una contrasenya (clau simètrica), seguint l'estàndard OpenPGP. És a dir, la mateixa clau serveix per xifrar i per desxifrar:

PGP_SYM_ENCRYPT(data text, psw text [, options text]) RETURNS bytea
PGP_SYM_DECRYPT(msg bytea, psw text [, options text]) RETURNS text
  • data / msg: text que es vol xifrar o dades xifrades que es volen desxifrar.
  • psw: contrasenya (clau) utilitzada per xifrar i desxifrar.
  • [options]: (opcional) paràmetres addicionals, com l'algorisme de xifratge (cipher-algo).

Documentació oficial: PGP Encryption Functions – PostgreSQL

Exemple: Encriptació i desencriptació

Es xifra un missatge amb una clau:

SELECT pgp_sym_encrypt('Missatge secret', 'clau_de_seguretat') AS dades_xifrades;
                            dades_xifrades
-------------------------------------------------------------------
 \xc30d0407030262...

A continuació, es desxifra amb la mateixa clau:

SELECT pgp_sym_decrypt(
    pgp_sym_encrypt('Missatge secret', 'clau_de_seguretat'),
    'clau_de_seguretat'
) AS missatge_original;
 missatge_original
--------------------
 Missatge secret

S'observa que el resultat xifrat és de tipus bytea i que només es recupera el text original amb la clau correcta.

Resum criptogràfic (digest i hmac)

La funció digest calcula un codi hash – Viquipèdia, és a dir, un resum de mida fixa que no es pot revertir per obtindre el text original:

digest(data text | bytea, type text) RETURNS bytea
  • data: text o dades binàries de què es calcula el hash.
  • type: algorisme de hash (md5, sha1, sha256, sha384, sha512).
Exemple: Hash amb SHA-256
SELECT encode(digest('passwd', 'sha256'), 'hex') AS hash_contrasenya;
                         hash_contrasenya
----------------------------------------------------------------
 0d6be69b264717f2dd33652e212b173104b4a647b7c11ae72e9885f11cd312fb

La funció hmac genera un codi d'autenticació de missatge (MAC). És semblant a digest, però utilitza una clau, de manera que només qui coneix la clau pot generar o comprovar el codi:

hmac(data text | bytea, key text | bytea, type text) RETURNS bytea
  • key: clau secreta utilitzada per generar el codi.

Documentació oficial: Hashing Functions – PostgreSQL

Exemple: MAC amb HMAC-SHA256
SELECT encode(hmac('Missatge important', 'clau_secreta_mac', 'sha256'), 'hex') AS mac_missatge;

Contrasenyes (crypt i gen_salt)

Per emmagatzemar contrasenyes de manera segura, pgcrypto ofereix les funcions crypt i gen_salt. Aquestes funcions afigen una sal (salt), un valor aleatori que es combina amb la contrasenya abans de calcular el hash. D'aquesta manera, dues contrasenyes iguals generen hashes diferents i s'eviten els atacs amb diccionaris precalculats:

crypt(password text, salt text) RETURNS text
gen_salt(type text [, iter_count int]) RETURNS text
  • password: contrasenya que es vol guardar o comprovar.
  • salt: sal generada amb gen_salt o hash guardat prèviament.
  • type: algorisme de la sal (md5, bf per a Blowfish, xdes).
  • [iter_count]: (opcional) nombre d'iteracions de l'algorisme.

Documentació oficial: Password Hashing Functions – PostgreSQL

Exemple: Emmagatzemar i validar una contrasenya
-- Emmagatzemar
SELECT crypt('passwd', gen_salt('bf')) AS contrasenya_emmagatzemada;

-- Validar (compara el hash calculat amb l'emmagatzemat)
SELECT (crypt('passwd', contrasenya_emmagatzemada) = contrasenya_emmagatzemada) AS coincideix;

S'observa que, per validar la contrasenya, es passa el hash guardat com a sal: crypt n'extrau la sal i, si la contrasenya és correcta, torna a obtindre el mateix hash.

Encriptació en trànsit (SSL/TLS)

Sense xifratge, qualsevol persona que puga capturar el trànsit de la xarxa pot llegir les consultes i els resultats, incloses les contrasenyes. Per activar les connexions xifrades, cal seguir aquests passos:

  1. Disposa d'un certificat (server.crt) i una clau privada (server.key) al directori de dades.

  2. Activa SSL a postgresql.conf:

    ssl = on
    ssl_cert_file = 'server.crt'
    ssl_key_file = 'server.key'
    
  3. Exigeix connexions xifrades a pg_hba.conf, amb el tipus hostssl en lloc de host:

    # TYPE     DATABASE  USER  ADDRESS      METHOD
    hostssl    all       all   0.0.0.0/0    scram-sha-256
    
  4. Reinicia el servidor (el paràmetre ssl és de context postmaster).

Documentació oficial: Secure TCP/IP Connections with SSL – PostgreSQL

Per la seua banda, el client indica el nivell de xifratge desitjat amb el paràmetre sslmode de la cadena de connexió:

Valors de sslmode
Valor Significat
disable No utilitza xifratge
require Exigeix una connexió xifrada, però no comprova el certificat
verify-ca A més, comprova que el certificat l'ha signat una autoritat de confiança
verify-full A més, comprova que el certificat correspon al nom del servidor
psql "postgresql://usuari@servidor:5432/basedades?sslmode=require"
📌 Aquest document pot quedar desactualitzat després d’imprimir-lo. Pots consultar la versió més recent a la pàgina web.
🌿 Abans d’imprimir aquest document, considera si és realment necessari. Redueix el consum de paper i ajuda a protegir el nostre entorn.