La crittografia dei dati è molto importante perché è un modo per proteggere i dati attuali e archiviati al fine di garantirne la riservatezza. Ciò impedisce un accesso e un utilizzo non autorizzati. In questo articolo, presenterò brevemente alcuni aspetti importanti della crittografia e decrittografia dei dati.
Sistemi di crittografia
In un sistema di crittografia, ci sono due componenti principali:l'algoritmo di crittografia, che è il metodo utilizzato per modificare il valore e la chiave di crittografia , la cui sicurezza dipende dalla vulnerabilità dei dati crittografati.
Oracle supporta due tipi di algoritmi di crittografia:algoritmi simmetrici (usa la stessa chiave per crittografare e decrittografare i dati) per crittografare i dati archiviati e algoritmi asimmetrici (vengono generate 2 chiavi:una chiave privata utilizzata per la decrittazione e una chiave pubblica che verrà utilizzata dal mittente del messaggio per crittografare il messaggio) utilizzata per l'accesso al database e per la comunicazione tra un database e un client.
Gli algoritmi di crittografia simmetrica disponibili in Oracle sono i seguenti:Data Encryption Standard (DES ) che crittografa un blocco di 64 bit di testo in 64 bit di testo crittografato, utilizzando una chiave di 56 bit, Triple Data Encryption Standard (3-DES ), una versione più avanzata di DES e Advanced Encryption Standard (AES ), che crittografa un blocco di 128 bit di testo in 128 bit di testo crittografato, utilizzando una chiave di 128.129 o 256 bit.
Si può notare che gli algoritmi di cifratura sopra citati utilizzano blocchi di dimensione fissa, e quindi il testo che deve essere cifrato verrà suddiviso in blocchi di una certa dimensione, richiesta dall'algoritmo utilizzato e quindi, l'algoritmo verrà applicato su ciascuno ottenuto blocco.
Tuttavia, cosa succede se la dimensione dei dati non è un multiplo della dimensione richiesta del blocco? La tecnica di riempimento deve essere utilizzato per riempire l'ultimo segmento del testo fino a raggiungere la dimensione di un blocco. Si può scegliere di riempire con zeri o di utilizzare lo schema di riempimento chiamato PKCS#5. Lo schema calcola la differenza per l'ultimo segmento di testo
d =dim_block – dim_data MOD dim_block
e riempie ogni byte mancante con il valore esadecimale 0x0d ,
dove dim_block è la dimensione in byte del blocco, richiesta dall'algoritmo
e riempie ogni byte mancante con il valore esadecimale 0x0d ,
dove dim_block è la dimensione in byte del blocco, richiesta dall'algoritmo
Tuttavia, cosa succede se il testo normale è composto da diversi blocchi da crittografare? La tecnica di concatenamento viene utilizzato, che stabilisce se la crittografia di un blocco dipende o meno dalla crittografia dei blocchi precedenti.
I seguenti tipi di concatenamento sono disponibile in Oracle:
- Libro di codici elettronici (CHAIN_ECB):ogni blocco è crittografato indipendentemente dal resto dei blocchi. Lo svantaggio è che si possono identificare schemi ripetitivi nel frammento di testo.
- Concatenamento di blocchi di cifratura (CHAIN_CBC):per ogni blocco, prima della cifratura, viene applicato un operatore XOR con un vettore. Per il primo blocco della sequenza viene utilizzato un vettore di inizializzazione, mentre per un blocco del resto della sequenza viene utilizzato il risultato della crittografia del blocco precedente come vettore di bit
- Feedback sulla cifratura (CHAIN_CFB):è simile a CBC, tranne per il fatto che l'operatore XOR viene applicato dopo la crittografia a blocchi.
- Risposte sull'output (CHAIN_OFB):è simile a CFB, tranne per il fatto che il risultato del blocco precedente viene crittografato prima dell'applicazione dell'operatore XOR
Per crittografare e decrittografare i dati, possiamo utilizzare il pacchetto DBMS_CRYPTO disponibile in ORACLE. Per utilizzare questo pacchetto, SYSDBA deve concedere agli utenti i diritti di esecuzione, utilizzando il comando:
GRANT EXECUTE ON dbms_crypto TO username;
Per la crittografia, dbms_crypto.encrypt viene utilizzato, che ha i seguenti parametri:
dbms_crypto.encrypt( clear_text IN RAW, operating_mode IN PLS_INTEGER, key IN RAW, initialization_vector IN RAW DEFAULT NULL) RETURN RAW;
Per la decrittazione, dbms_crypto.decrypt viene utilizzato, che ha i seguenti parametri:
dbms_crypto.decrypt( clear_text IN RAW, operating_mode IN PLS_INTEGER, key IN RAW, initialization_vector IN RAW DEFAULT NULL) RETURN RAW;
Una modalità di funzionamento è formata da:
codice algoritmo + codice di riempimento + codice di concatenamento
Ecco alcuni esempi di crittografia e decrittografia dei dati:
create or replace PROCEDURE encryption(text IN VARCHAR2, encrypted text OUT VARCHAR2) AS raw_set RAW(100); raw_password RAW(100); encryption_result RAW(100); encryption_password VARCHAR2(100) := '[email protected]%5,:QxV'; operation_mode NUMBER; BEGIN raw_set:=utl_i18n.string_to_raw(text,'AL32UTF8'); raw_password := utl_i18n.string_to_raw(encryption_password,'AL32UTF8'); operation_mode:=DBMS_CRYPTO.ENCRYPT_DES + DBMS_CRYPTO.PAD_ZERO + DBMS_CRYPTO.CHAIN_ECB; encryption_result:=DBMS_CRYPTO.ENCRYPT(raw_set,operation_mode,raw_password); dbms_output.put_line(encryption_result); encryptedtext := RAWTOHEX (encryption_result); END; variable result_encryption varchar2(200) exec encryption('Text to be encrypted', :result_encryption); print result_encryption
create or replace PROCEDURE decryption (encrypted_text IN VARCHAR2, decrypted_text OUT VARCHAR2) AS raw_set RAW(100); raw_password RAW(100); decryption_result RAW(100); decryption_password VARCHAR2(100) := '[email protected]%5,:QxV'; operation_mode NUMBER; BEGIN raw_set:=HEXTORAW(encrypted_text); raw_password :=utl_i18n.string_to_raw(decryption_password,'AL32UTF8'); operation_mode:=DBMS_CRYPTO.ENCRYPT_DES + DBMS_CRYPTO.PAD_ZERO + DBMS_CRYPTO.CHAIN_ECB; decryption_result:=DBMS_CRYPTO.DECRYPT(raw_set,operation_mode,raw_password); dbms_output.put_line(decryption_result); decrypted_text := utl_i18n.raw_to_char (decryption_result,'AL32UTF8'); END; variable result_decryption varchar2(200) exec decryption(:result_encryption,:result_decryption) print result_decryption
Sfide relative alla crittografia dei dati
Gestione delle chiavi di crittografia per i dati
È difficile per gli utenti del database generare manualmente chiavi di crittografia efficienti, che abbiano la lunghezza richiesta per l'algoritmo di crittografia. Per quanto riguarda la fornitura manuale della chiave di crittografia come set di stringhe (convertito poi in RAW), la lunghezza del set viene calcolata utilizzando la seguente formula:
L_set =Lunghezza_chiave_in_bit / 8 (caratteri)
Ad esempio, per ENCRYPT_AES128, la chiave ha 128 bit e il set avrà la lunghezza L_set =128/8 =16 caratteri.
Se viene fornita la chiave "1234567890123456", verrà accettata, mentre la chiave "1234" genererà l'eccezione "lunghezza della chiave troppo corta".
Per il resto degli algoritmi, la tabella seguente fornisce la lunghezza effettiva della chiave:
Generazione e trasmissione delle chiavi
I dati sono crittografati in modo sicuro purché la chiave utilizzata per la crittografia sia sicura. Pertanto, la chiave di crittografia deve essere generata in modo sicuro. Il pacchetto funzione RANDOMBYTES of DBMS_CRYPTO offre una generazione sicura di numeri casuali e implementa l'algoritmo del generatore di numeri casuali. Gli sviluppatori non devono utilizzare il pacchetto DBMS_RANDOM perché genera numeri pseudo-casuali, che possono risultare in una pseudo-sicurezza.
La funzione RANDOMBYTES viene utilizzata come segue:
chiave RAW (nr_byte);
chiave:=DBMS_CRYPTO.randombytes (nr_bytes);
dove nr_bytes rappresenta il numero di byte della chiave di crittografia
Quando la chiave viene passata da un'applicazione al database, deve essere crittografata per non essere rubata durante la trasmissione. Oracle Advanced Security fornisce la crittografia di rete, che protegge i dati e le chiavi crittografiche nel loro transito in rete.
Una volta generate le chiavi, queste devono essere conservate al sicuro, poiché la loro divulgazione potrebbe compromettere la sicurezza dei dati crittografati. Ci sono tre opzioni per conservare la chiave:
- a livello di database:memorizzato nel database (in un'apposita tabella) o in un file di database esterno
- a livello di record:memorizzato nel database (in un'apposita tabella)
- una combinazione tra le due tipologie precedenti:c'è una chiave maestra a livello di database e per ogni record c'è una chiave. Viene utilizzata una chiave ibrida sia per la crittografia che per la decrittografia:hybrid_key =master_key XOR record_key (per la funzione XOR, esiste una funzione PL/SQL – UTL_RAW.bit_xor).
Qual è la chiave più efficiente? È la chiave ibrida. Se l'intero database viene rubato, i dati non possono essere decrittografati quando la chiave principale è archiviata nel file system. Se la chiave principale o un record di chiave vengono rubati, il resto del record sarebbe comunque protetto.
Crittografia dei dati trasparenti (TDE)
Un'altra funzione di sicurezza offerta da Oracle è la Transparent Data Encryption (TDE) , una struttura disponibile da Oracle 10g. TDE consente di dichiarare una colonna crittografata a livello di tabella del database. Quando si inseriscono i dati nella colonna crittografata, Oracle crittografa automaticamente i dati e ne archivia la crittografia nel database.
Qualsiasi query SELECT decrittograferà automaticamente i dati. È importante ricordare che la Crittografia dei dati trasparenti non fa differenza tra gli utenti e fornisce i dati decrittografati indipendentemente da chi sta interrogando il database. Non tutte le colonne possono essere crittografate da TDE:le colonne della chiave esterna (chiave esterna) non possono essere crittografate con questo metodo.
Ad esempio:si consideri una tabella denominata ACCOUNT con lo schema relazionale ACCOUNT (id_account#, card_series, possessor, amount), dove id_account è considerata come chiave primaria, infatti indicata dal segno '#'. Supponiamo di voler dichiarare la card_series e equilibrio colonne da crittografare. Questo può essere fatto con quanto segue:
ALTER TABLE accont MODIFY (card_series ENCRYPT USING 'AES128'); ALTER TABLE accont MODIFY (balance ENCRYPT USING 'AES128');
Affinché questo metodo funzioni, è necessario creare e configurare un portafoglio.
Perché la Crittografia dei dati trasparenti impedire la decrittazione dei dati in caso di furto del database? Bene, tutte le colonne crittografate di una tabella T utilizzano la stessa chiave privata Key_T. Se abbiamo più tabelle, ,…, che hanno colonne crittografate, allora ci sono n chiavi private, Key_,…,Key_. Ogni chiave privata Key_, j=1,n viene crittografata con la chiave master, Key_Master, e il risultato di questa crittografia viene archiviato nel dizionario dei dati. La chiave principale è archiviata esternamente in un portafoglio.
Ora, diamo un'occhiata ai passaggi per questa crittografia automatica. Sono:
- ottenere il master Key_Master dal portafoglio esterno
- Decrittografia della chiave privata, Key_, utilizzando la chiave master
- crittografia dei dati da inserire tramite chiave privata, Key_
- memorizzare i dati crittografati nelle colonne della tabella
I passaggi per la decrittazione automatica sono:
- ottenere la chiave principale, Key_Master, dal portafoglio esterno
- Decrittografia della chiave privata, Key_, utilizzando la chiave master
- Decrittografia dei dati utilizzando la chiave privata, Key_
- restituendo il risultato
Che dire dell'integrità dei dati durante la crittografia? Qui usiamo la tecnica dell'hashing.
Hashing
La crittografia dei dati garantisce la riservatezza dei dati ma non ne garantisce l'integrità. Per evitare questo problema, oltre al fatto che solo i dati originali devono essere crittografati, possiamo utilizzare una tecnica chiamata hashing . ci sono due importanti vantaggi:non permette di decifrare i valori originali ed è deterministico (il che significa che applicato ripetutamente agli stessi dati, genera lo stesso risultato). Oracle consente i seguenti algoritmi di hashing:MD5 e SHA-1.
Utilizzo:
DBMS_CRYPTO.Hash ( original_set IN RAW, operation_mode IN PLS_INTEGER) RETURN RAW; where operation_mode is either DBMS_CRYPTO.HASH_MD5 or DBMS_CRYPTO.HASH_SH1
Esempio:
set serveroutput on DECLARE credit_card_no VARCHAR2(19) := '1234-5678-1234-5678'; credit_card_no_raw RAW(128) := utl_raw.cast_to_raw(credit_card_no); encrypted_raw RAW(2048); BEGIN encrypted_raw:=dbms_crypto.hash(credit_card_no_raw, dbms_crypto.hash_md5); dbms_output.put_line('MD5: ' || encrypted_raw); END;
Crittografia dei dati indicizzati
Non è consigliabile per gli sviluppatori crittografare i dati indicizzati. Se un indice di una colonna contiene valori crittografati, l'indice può essere utilizzato per un semplice controllo ed è inutilizzabile per altri scopi.
Si supponga, ad esempio, che un'azienda utilizzi il numero di identificazione personale per il numero del dipendente archiviato in una tabella del database. Ovviamente, quei numeri sono considerati dati sensibili e riservati e l'azienda vuole crittografare la colonna in cui è archiviato. Poiché questa colonna contiene valori univoci, è possibile eseguire un indice su di essa per ottenere prestazioni migliori. Ciò significa che l'indice conterrà dati crittografati e sarebbe sostanzialmente inutilizzabile.
Conclusione
Per concludere, è molto importante proteggere i dati sensibili crittografandoli e decrittografandoli. Si dovrebbe essere consapevoli di questo aspetto e implementare di conseguenza la sicurezza del database.
Riferimenti:
- Sviluppo di applicazioni utilizzando la crittografia dei dati
- Feuerstein Steven (2009) Programmazione Oracle PL/SQL (5a edizione). Editoria O'Reilly. ISBN 978-0-596-51446-4. Capitolo 23 "Sicurezza delle applicazioni e PL/SQL"
- Modalità operativa di cifratura a blocchi