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. Oracle DB 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 Oracle DB.

Tipus d'encriptació en Oracle DB

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, com els fitxers de dades, els fitxers temporals, els fitxers de redo/undo (segons la configuració) i les còpies de seguretat de RMAN.
  • Encriptació en trànsit (in-transit): protegeix les dades durant la transmissió per la xarxa, mitjançant Oracle Native Network Encryption (NNE) o TLS/SSL en les connexions Oracle Net.

Encriptació de les dades en disc

Les dades que Oracle DB guarda en disc es poden encriptar mitjançant dos procediments:

  • Funcions d'encriptació: l'aplicació o l'administrador encripten i desencripten la informació explícitament amb les funcions del paquet DBMS_CRYPTO.
  • Encriptació transparent (Transparent Data Encryption, TDE): Oracle encripta les dades en el disc de manera transparent per a l'usuari, sense canvis en les consultes.

Funcions d'encriptació (DBMS_CRYPTO)

Oracle proporciona el paquet DBMS_CRYPTO, que conté les funcions per encriptar, desencriptar i calcular resums de la informació.

Documentació oficial: DBMS_CRYPTO – Oracle DB

Els algorismes criptogràfics que proporciona són els següents:

  • DES: Data Encryption Standard
  • AES: Advanced Encryption Standard
  • SHA-2: Secure Hash Algorithm, version 2

Encriptació (ENCRYPT)

La funció ENCRYPT encripta unes dades, que posteriorment es podran desencriptar amb la mateixa clau:

DBMS_CRYPTO.ENCRYPT(
   src IN RAW,
   typ IN PLS_INTEGER,
   key IN RAW,
   iv  IN RAW          DEFAULT NULL
)
RETURN RAW;
  • src: dades en format RAW, normalment convertides des de VARCHAR2 amb UTL_RAW.CAST_TO_RAW.
  • typ: algorisme i mode de xifratge. És la suma d'un algorisme, un mode d'encadenament i un farciment, o bé una de les constants predefinides.

    Valors de typ

    Es recomana utilitzar algorismes i modes forts, com AES256 amb CBC i PKCS5.

    -- Block Cipher Algorithms
    ENCRYPT_DES        CONSTANT PLS_INTEGER            :=     1;  -- 0x0001
    ENCRYPT_3DES_2KEY  CONSTANT PLS_INTEGER            :=     2;  -- 0x0002
    ENCRYPT_3DES       CONSTANT PLS_INTEGER            :=     3;  -- 0x0003
    ENCRYPT_AES        CONSTANT PLS_INTEGER            :=     4;  -- 0x0004
    ENCRYPT_PBE_MD5DES CONSTANT PLS_INTEGER            :=     5;  -- 0x0005
    ENCRYPT_AES128     CONSTANT PLS_INTEGER            :=     6;  -- 0x0006
    ENCRYPT_AES192     CONSTANT PLS_INTEGER            :=     7;  -- 0x0007
    ENCRYPT_AES256     CONSTANT PLS_INTEGER            :=     8;  -- 0x0008
    
    -- Block Cipher Chaining Modifiers
    CHAIN_CBC          CONSTANT PLS_INTEGER            :=   256;  -- 0x0100
    CHAIN_CFB          CONSTANT PLS_INTEGER            :=   512;  -- 0x0200
    CHAIN_ECB          CONSTANT PLS_INTEGER            :=   768;  -- 0x0300
    CHAIN_OFB          CONSTANT PLS_INTEGER            :=  1024;  -- 0x0400
    
    -- Block Cipher Padding Modifiers
    PAD_PKCS5          CONSTANT PLS_INTEGER            :=  4096;  -- 0x1000
    PAD_NONE           CONSTANT PLS_INTEGER            :=  8192;  -- 0x2000
    PAD_ZERO           CONSTANT PLS_INTEGER            := 12288;  -- 0x3000
    PAD_ORCL           CONSTANT PLS_INTEGER            := 16384;  -- 0x4000
    
    -- Stream Cipher Algorithms
    ENCRYPT_RC4        CONSTANT PLS_INTEGER            :=   129;  -- 0x0081
    
    
    -- Convenience Constants for Block Ciphers
    DES_CBC_PKCS5      CONSTANT PLS_INTEGER            := ENCRYPT_DES
                                                          + CHAIN_CBC
                                                          + PAD_PKCS5;
    
    DES3_CBC_PKCS5     CONSTANT PLS_INTEGER            := ENCRYPT_3DES
                                                          + CHAIN_CBC
                                                          + PAD_PKCS5;
    
    AES_CBC_PKCS5      CONSTANT PLS_INTEGER            := ENCRYPT_AES
                                                          + CHAIN_CBC
                                                          + PAD_PKCS5;
    

    Codi font del paquet DBMS_CRYPTO.

  • key: clau en format RAW. La seua mida ha de ser compatible amb l'algorisme.

    Mida de la clau segons l'algorisme
    Algorisme Mida clau (bytes)
    DES 8
    3DES (2-key) 16
    3DES (3-key) 24
    AES-128 16
    AES-192 24
    AES-256 32

    Mida de claus segons l'algorisme d'encriptació

  • iv: (opcional) vector d'inicialització (IV), necessari en modes com CBC.

    Si l'algorisme requereix IV, cal generar-lo i conservar-lo per poder desencriptar.

Documentació oficial: ENCRYPT Function – Oracle DB

Exemple: Encriptació d'un missatge

S'encripta el text Missatge secret amb una clau de 32 bytes:

SELECT RAWTOHEX(
         DBMS_CRYPTO.ENCRYPT(
           UTL_RAW.CAST_TO_RAW('Missatge secret'),
           5128, -- DBMS_CRYPTO.AES_CBC_PKCS5
           UTL_RAW.CAST_TO_RAW(RPAD('CLAU DE SEGURETAT', 32, ' '))
         )
       ) AS dades_xifrades
FROM dual;
683CE2F6F481902D69586F54E5D6AE47

S'observa que el resultat és una cadena hexadecimal il·legible sense la clau.

Desencriptació (DECRYPT)

La funció DECRYPT desencripta unes dades encriptades amb ENCRYPT:

DBMS_CRYPTO.DECRYPT(
     src IN RAW,
     typ IN PLS_INTEGER,
     key IN RAW,
     iv  IN RAW          DEFAULT NULL
)
RETURN RAW;
  • src: dades encriptades en format RAW.
  • typ, key i iv: els mateixos valors que es van utilitzar amb ENCRYPT.

Documentació oficial: DECRYPT Function – Oracle DB

Exemple: Desencriptació d'un missatge

Es desencripta un missatge amb el mateix algorisme i la mateixa clau:

SELECT UTL_RAW.CAST_TO_VARCHAR2(
     DBMS_CRYPTO.DECRYPT(
       HEXTORAW('54C6096F3506620FCBBEF04D7A5DCBD9'),
       5128, -- DBMS_CRYPTO.AES_CBC_PKCS5
       UTL_RAW.CAST_TO_RAW(RPAD('CLAU DE SEGURETAT', 32, ' '))
     )
   ) AS missatge_original
FROM dual;
Missatge secret

Resum criptogràfic (HASH)

La funció HASH calcula un codi hash – Viquipèdia, és a dir, un resum de mida fixa a partir del qual no es pot recuperar la informació original:

DBMS_CRYPTO.HASH(
    src IN RAW | BLOB | CLOB,
    typ IN PLS_INTEGER
)
RETURN RAW;
  • src: dades en format RAW, BLOB o CLOB.
  • typ: algorisme de hash.

    Valors de typ
    HASH_MD4        CONSTANT PLS_INTEGER            :=    1;  -- 0x0001
    HASH_MD5        CONSTANT PLS_INTEGER            :=    2;  -- 0x0002
    HASH_SHA1       CONSTANT PLS_INTEGER            :=    3;  -- 0x0003
    HASH_SH256      CONSTANT PLS_INTEGER            :=    4;  -- 0x0004
    HASH_SH384      CONSTANT PLS_INTEGER            :=    5;  -- 0x0005
    HASH_SH512      CONSTANT PLS_INTEGER            :=    6;  -- 0x0006
    

    Codi font del paquet DBMS_CRYPTO.

Documentació oficial: HASH Function – Oracle DB

Exemple: Hash amb SHA-256

Es calcula el hash SHA-256 de la contrasenya passwd:

SELECT
    DBMS_CRYPTO.HASH(
        UTL_RAW.CAST_TO_RAW('passwd'),
        4 -- DBMS_CRYPTO.HASH_SH256
    ) AS hash_contrasenya
FROM dual;
0D6BE69B264717F2DD33652E212B173104B4A647B7C11AE72E9885F11CD312FB

Codi d'autenticació de missatge (MAC)

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

DBMS_CRYPTO.MAC(
    src IN RAW | BLOB | CLOB,
    typ IN PLS_INTEGER,
    key IN RAW
)
RETURN RAW;
  • src: dades en format RAW, BLOB o CLOB.
  • typ: algorisme de MAC.

    Valors de typ
    MAC_HMAC_MD5        CONSTANT PLS_INTEGER            :=    1;  -- 0x0001
    MAC_HMAC_SHA1       CONSTANT PLS_INTEGER            :=    2;  -- 0x0002
    MAC_HMAC_SH256      CONSTANT PLS_INTEGER            :=    3;  -- 0x0003
    MAC_HMAC_SH384      CONSTANT PLS_INTEGER            :=    4;  -- 0x0004
    MAC_HMAC_SH512      CONSTANT PLS_INTEGER            :=    5;  -- 0x0005
    

    Codi font del paquet DBMS_CRYPTO.

  • key: clau en format RAW.

Documentació oficial: MAC Function – Oracle DB

Exemple: MAC amb HMAC-SHA256

Es genera el MAC d'un missatge amb una clau secreta:

SELECT
    DBMS_CRYPTO.MAC(
        UTL_RAW.CAST_TO_RAW('Missatge important'),
        3, -- DBMS_CRYPTO.MAC_HMAC_SH256,
        UTL_RAW.CAST_TO_RAW(rpad('CLAU_SECRETA_MAC', 32, ' '))
    ) AS mac_missatge
FROM dual;
8CC6AA48DFF90A2B846CAF9943FDD790E541F7F070771EA244ACFFEB749D8DB6

Transparent Data Encryption (TDE)

TDE és la solució d'Oracle per xifrar les dades en disc de manera transparent per a les aplicacions. Oracle xifra les dades abans d'escriure-les en disc i les desxifra quan es llegeixen, de manera que les aplicacions no necessiten cap canvi.

Documentació oficial: Introduction to Transparent Data Encryption – Oracle DB

TDE es pot aplicar de dues maneres:

  • Encriptació de columnes: xifra columnes concretes mitjançant claus de columna.
  • Encriptació de tablespaces: xifra els fitxers físics associats al tablespace. És la solució més habitual per xifrar dades en disc a gran escala.

En tots dos casos, TDE es basa en una jerarquia de claus (Figura 1). La clau mestra de TDE (TDE Master Key) xifra les claus de tablespace i de columna, que són les que xifren realment les dades. D'aquesta manera, n'hi ha prou amb protegir la clau mestra.

Arquitectura de claus en TDE

Oracle

Figura 1. Arquitectura de claus en TDE.

Magatzem de claus per contrasenya

Per configurar TDE, el primer pas és crear i configurar un magatzem de claus (keystore o wallet), on es guarda la clau mestra. El tipus més bàsic es protegeix amb una contrasenya, que cal indicar per obrir-lo i obtindre les claus.

Documentació oficial: Cifrar los datos en la base de datos origen – Oracle

El procediment és el següent:

  1. Comprova que no existeix cap magatzem de claus amb la vista V$ENCRYPTION_WALLET:

    SELECT wrl_parameter, status, wallet_type FROM V$ENCRYPTION_WALLET;
    
    WRL_PARAMETER                     STATUS     WALLET_TYPE
    --------------------------------- ---------- -------------
    /opt/oracle/admin/XE/wallet       NOT FOUND  PASSWORD
    
  2. Crea la carpeta wallet, on s'emmagatzemaran les claus:

    mkdir -p /opt/oracle/admin/XE/wallet/
    
  3. Crea el magatzem de claus per contrasenya:

    El magatzem de claus es comparteix entre totes les PDB de la CDB.

    ADMINISTER KEY MANAGEMENT
        CREATE KEYSTORE '/opt/oracle/admin/XE/wallet'
        IDENTIFIED BY "wallet_password";
    
    SELECT wrl_parameter, status, wallet_type FROM V$ENCRYPTION_WALLET;
    
    WRL_PARAMETER                     STATUS     WALLET_TYPE
    --------------------------------- ---------- -------------
    /opt/oracle/admin/XE/wallet       CLOSED     PASSWORD
    
  4. Obri el magatzem de claus:

    ADMINISTER KEY MANAGEMENT
        SET KEYSTORE OPEN
        IDENTIFIED BY "wallet_password";
    
    SELECT wrl_parameter, status, wallet_type FROM V$ENCRYPTION_WALLET;
    
    WRL_PARAMETER                     STATUS              WALLET_TYPE
    --------------------------------- ------------------- -------------
    /opt/oracle/admin/XE/wallet       OPEN_NO_MASTER_KEY  PASSWORD
    
  5. Crea la clau mestra:

    La clau mestra no es comparteix entre la CDB i les PDB: s'ha de crear en cada PDB per separat.

    ADMINISTER KEY MANAGEMENT
        SET KEY
        IDENTIFIED BY "wallet_password"
        WITH BACKUP;
    
    SELECT wrl_parameter, status, wallet_type FROM V$ENCRYPTION_WALLET;
    
    WRL_PARAMETER                     STATUS    WALLET_TYPE
    --------------------------------- --------  -------------
    /opt/oracle/admin/XE/wallet       OPEN      PASSWORD
    

    Les claus creades es poden comprovar amb la vista V$ENCRYPTION_KEYS:

    SELECT key_id, keystore_type, creator, creator_instance_name, creator_pdbname
    FROM V$ENCRYPTION_KEYS;
    
    KEY_ID                                                  KEYSTORE_TYPE        CREATOR    CREATOR_INSTANCE_NAME    CREATOR_PDBNAME
    ------------------------------------------------------  -------------------  ---------  -----------------------  ---------------
    AT9UAu+2a0/wv6Eq8GiWj80AAAAAAAAAAAAAAAAAAAAAAAAAAAAA    SOFTWARE KEYSTORE    SYS        XE                       XEPDB1
    AWECzapuSk8Tvz9jbhztwr8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA    SOFTWARE KEYSTORE    SYS        XE                       CDB$ROOT
    

Magatzem de claus AUTO_LOGIN

El problema dels magatzems de claus per contrasenya és que cal indicar la contrasenya en cada operació sobre el magatzem, com obrir-lo o tancar-lo. A més, cada vegada que es reinicia la instància, l'administrador ha de tornar a obrir el magatzem.

Per evitar aquests inconvenients, es pot crear un magatzem AUTO_LOGIN, que obri automàticament el magatzem de claus per contrasenya:

ADMINISTER KEY MANAGEMENT
CREATE AUTO_LOGIN KEYSTORE
FROM KEYSTORE  '/opt/oracle/admin/XE/wallet'
IDENTIFIED BY "wallet_password";

SHUTDOWN IMMEDIATE;
STARTUP MOUNT;

SELECT wrl_parameter, status, wallet_type FROM V$ENCRYPTION_WALLET;
WRL_PARAMETER                     STATUS    WALLET_TYPE
--------------------------------- --------  -------------
/opt/oracle/admin/XE/wallet       OPEN      AUTO_LOGIN

S'observa que, després de reiniciar, el magatzem està obert (OPEN) sense haver indicat la contrasenya.

Encriptació de tablespaces

Per crear un tablespace nou encriptat amb TDE, s'utilitza la clàusula ENCRYPTION en la sentència CREATE TABLESPACE:

CREATE TABLESPACE ENCRYPTED_TS
    DATAFILE '/opt/oracle/oradata/XE/XEPDB1/tbsec.dbf'
    SIZE 50M LOGGING EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO
    DEFAULT STORAGE(ENCRYPT) ENCRYPTION USING 'AES256' ENCRYPT;

La vista DBA_TABLESPACES permet comprovar que el tablespace s'ha creat encriptat:

SELECT TABLESPACE_NAME, ENCRYPTED
    FROM dba_tablespaces;
TABLESPACE_NAME         ENCRYPTED
----------------------- ----------
SYSTEM                  NO
SYSAUX                  NO
UNDOTBS1                NO
TEMP                    NO
USERS                   NO
ENCRYPTED_TS            YES

També es pot encriptar un tablespace existent amb la sentència ALTER TABLESPACE:

ALTER TABLESPACE USERS
    ENCRYPTION USING 'AES256' ENCRYPT;

SELECT TABLESPACE_NAME, ENCRYPTED
    FROM dba_tablespaces;
TABLESPACE_NAME         ENCRYPTED
----------------------- ----------
SYSTEM                  NO
SYSAUX                  NO
UNDOTBS1                NO
TEMP                    NO
USERS                   YES
ENCRYPTED_TS            YES

Documentació oficial: Encryption Conversions for Tablespaces and Databases – Oracle DB

Encriptació de columnes

Quan només cal protegir unes quantes dades sensibles, es poden encriptar columnes concretes d'una taula amb la clàusula ENCRYPT en la sentència CREATE TABLE o ALTER TABLE:

CREATE TABLE EMPLOYEES_SEC (
    EMP_ID NUMBER PRIMARY KEY,
    EMP_NAME VARCHAR2(100),
    SALARY NUMBER ENCRYPT USING 'AES256' NO SALT
);
L'usuari SYS no pot crear taules amb columnes encriptades.
ORA-28336: cannot encrypt SYS owned objects

https://docs.oracle.com/error-help/db/ora-28336/
28336. 0000 -  "cannot encrypt SYS owned objects"
*Cause:    An attempt was made to encrypt columns in a table that were
           owned by SYS.
*Action:   Do not attempt to encrypt columns in a table that are
           owned by SYS or consider using tablespace encryption.

La vista USER_ENCRYPTED_COLUMNS permet comprovar quines columnes estan encriptades:

SELECT * FROM USER_ENCRYPTED_COLUMNS;
TABLE_NAME        COLUMN_NAME  ENCRYPTION_ALG     SALT    INTEGRITY_ALG
----------------  -----------  -----------------  ------  -----------
EMPLOYEES_SEC     SALARY       AES 256 bits key   NO      SHA-1

Documentació oficial: Encrypting Columns in Tables – Oracle DB

📌 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.