Questa pagina è stata tradotta automaticamente. Leggi l'originale in inglese. English

Libreria IBSurgeon

Come funziona la crittografia del database Firebird

(c) Alexey Kovyazin, IBSurgeon, Alex Peshkoff, Firebird Project, 2021

L’articolo si basa sui materiali del workshop “Database Encryption” alla Firebird Conference 2019 a Berlino, in Germania. Descrive come funziona la crittografia dei database Firebird, a livello di server, lato client, come configurare la crittografia del database, come usarla dai vari tipi di applicazioni (Delphi, Java, .NET). Gli esempi dell’articolo si basano su IBSurgeon Firebird Encryption Framework (FEPF) ma possono essere adattati alla maggior parte delle implementazioni attualmente disponibili di plugin di crittografia.

Contenuti:

  1. Perché abbiamo bisogno della crittografia del database (e quando non ne abbiamo bisogno)?
  2. Come funziona la crittografia del database Firebird lato server
  3. Quale parte del database viene crittografata?
  4. Quando vengono crittografate le pagine dei dati?
  5. Come proteggere il trasferimento delle chiavi?
  6. Come funziona la crittografia Firebird lato client
  7. Applicazioni native
  8. Applicazioni Java
  9. Applicazioni .NET
  10. Installazione e configurazione
  11. Come monitorare l’avanzamento della crittografia
  12. Riepilogo

1. Perché abbiamo bisogno della crittografia del database (e quando non ne abbiamo bisogno)?

La crittografia dei database Firebird è stata introdotta nella versione Firebird 3.0 (insieme alla crittografia del protocollo di trasferimento, che spesso viene confusa con l’argomento in discussione) e ha notevolmente aumentato le capacità di proteggere i dati da accessi non autorizzati. Tuttavia, non è una panacea, ed è necessario comprenderne i punti di forza e di debolezza per usarla correttamente.

In questo articolo, esaminiamo i dettagli interni della crittografia del database a livello base, per dare agli sviluppatori di applicazioni Firebird una migliore comprensione di come funziona la crittografia del database.

Quindi, perché abbiamo bisogno della crittografia del database?

  1. Per proteggere i database con dati sensibili/di valore dal furto “fisico”. Se un intruso ruba il disco con una copia del database crittografato o ottiene in qualche modo una copia del file del database, non sarà possibile leggere i dati senza una chiave appropriata, così come non sarà possibile utilizzare software di recupero come FirstAID per estrarre i dati. Naturalmente, dipende dall’algoritmo di crittografia e dalla potenza di calcolo, ma decifrare AES256 richiederà troppo tempo o risorse di calcolo troppo costose.
  2. Per proteggere il database dall’accesso da parte di applicazioni non autorizzate senza chiavi di crittografia. Esempi sono:
    • accesso diretto con uno strumento di sviluppo da parte di una persona non autorizzata, per modificare informazioni sensibili (ad esempio, transazioni di denaro),
    • modifica o furto della logica di business (testi di stored procedure e trigger).
  3. Proteggere i database con dati precompilati dall’esportazione o dall’accesso da parte di applicazioni non autorizzate.
  4. I governi hanno recentemente introdotto leggi sulla protezione dei dati (GDPR/DSVGO in Europa, LGPD in Brasile, ecc.) che richiedono, tra le altre cose, un livello più elevato di protezione per i dati personali e altri dati sensibili, e la crittografia è menzionata come una delle misure di protezione adeguate.

Quando la crittografia del database non è utile?

In alcuni casi è meglio utilizzare le funzionalità di sicurezza e configurazione di Firebird invece della crittografia del database:

  • Per proteggere il database dall’accesso fisico tramite rete, è necessario configurare l’accesso di rete: cioè, chiudere le cartelle condivise di rete, perché Firebird non richiede l’accesso condiviso di rete ai file del database, e rafforzare i permessi di sicurezza (per Linux, ad esempio, i file del database devono avere accesso in lettura-scrittura solo per l’utente “firebird”).
  • Per limitare l’accesso al database specifico per un sottoinsieme specifico di utenti, la soluzione più semplice sarà configurare un database di sicurezza separato.
  • Per limitare l’accesso agli oggetti del database (tabelle, stored procedure) è necessario utilizzare i meccanismi di sicurezza di Firebird: utenti, ruoli, ecc.

Naturalmente, entrambe le liste sopra sono incomplete, ma danno un’idea di quando si ha bisogno o non si ha bisogno della crittografia del database.

2. Come funziona la crittografia del database Firebird lato server

Esaminiamo i dettagli interni della crittografia del database Firebird, e iniziamo con la parte server.

2.1. Quale parte del database viene crittografata?

La prima cosa che dobbiamo considerare è quale parte del database viene crittografata? Come probabilmente sapete, il database Firebird è composto da parti di dimensioni uguali, chiamate “pagine del database”. Esistono diversi tipi di tali pagine, ogni tipo serve a uno scopo specifico.

Di seguito potete vedere la figura con i principali tipi di dati:

Figura 1. Tipi di pagine del database

Alcune pagine sono progettate per memorizzare i dati degli utenti, e altre sono necessarie per memorizzare informazioni di sistema, come transazioni e pagine di inventario delle pagine (maggiori dettagli sulle pagine del database sono disponibili qui).

Quando il database Firebird viene crittografato, solo le pagine con i dati utente vengono crittografate: pagine dati, indici, generatori e BLOB:

Figura 2. Solo le pagine del database con i dati degli utenti vengono crittografate

Si prega di notare che i metadati del database (stored procedure, tabelle, viste, trigger, nomi dei generatori, ecc.) non differiscono dai “dati degli utenti” all’interno della parte del motore responsabile della crittografia, e vengono crittografati.

Perché le pagine di sistema non vengono crittografate? Principalmente per motivi di prestazioni e per il fatto che non contengono dati sensibili che richiedono protezione.

La pagina di intestazione del database non è crittografata, perché contiene informazioni necessarie per la crittografia (ad esempio, il nome della chiave).

2.2. Quando vengono crittografate le pagine dei dati?

Quando un utente esegue una SELECT dal database crittografato, i dati vengono letti dal file crittografato ma arrivano alla griglia dell’applicazione con il set di risultati in forma non crittografata.

Consideriamo i dettagli di questo processo:

Figura 3. Quando vengono crittografate le pagine del database?

Di solito, il processo inizia con una serie di letture delle pagine del database da un file di database, e vengono memorizzate nella cache dei file del sistema operativo.

Firebird può anche essere configurato per bypassare la cache dei file e utilizzare solo la propria cache, ma per impostazione predefinita viene utilizzata la cache dei file.

Dopo di che, Firebird legge le pagine e le inserisce nella cache delle pagine di Firebird (definita dal parametro DefaultDBCachePages in firebird.conf e/o databases.conf o nella pagina di intestazione del database).

Quindi, le pagine dalla cache vengono selezionate per il set di risultati della particolare istruzione SQL (SELECT nel nostro esempio).

La figura seguente mostra i dettagli:

Figura 4. Le pagine vengono crittografate tra la cache di Firebird e la cache dei file del sistema operativo

Quindi, le pagine del database vengono crittografate nella cache dei file del sistema operativo ma arrivano alla cache delle pagine di Firebird non crittografate, e viceversa.

La parte del software Firebird responsabile della crittografia/decrittografia è chiamata “plugin di crittografia”. Poiché la maggior parte delle implementazioni dei plugin (note agli autori) si chiamano DbCrypt, ci riferiremo ad esso come DbCrypt.

Nella figura seguente potete vedere le varianti per Windows (DbCrypt.dll) e Linux (libDbCrypt.so):

Figura 5. Il plugin di crittografia (DbCrypt) esegue la crittografia/decrittografia

Se guardate questa immagine abbastanza a lungo, la prossima domanda apparirà abbastanza rapidamente: come fa DbCrypt a ottenere la chiave appropriata per crittografare/decrittografare le pagine del database?

La risposta: c’è un altro plugin per la gestione delle chiavi.

Il nome tipico per la gestione delle chiavi è KeyHolder, che funge da struttura di archiviazione/gestione delle chiavi per il plugin di crittografia (DbCrypt). KeyHolder implementa l’interfaccia per la gestione delle chiavi utilizzata da DbCrypt.

Figura 6. DbCrypt e KeyHolder

Cosa significa “gestione delle chiavi”?

Nel caso più semplice, DbCrypt può leggere le chiavi dal file sul server. Il file può essere un semplice file di testo, che può essere nascosto in un luogo “segreto” o su una chiavetta USB, oppure può essere un file crittografato (usando Windows Crypto API, ad esempio, o con una chiave interna incorporata).

Il file delle chiavi può contenere diverse chiavi, memorizzate, per comodità, come elenco nominato, e può apparire così (l’esempio seguente è tratto dal framework di plugin di crittografia IBSurgeon):

Code
Key=Red 0xec,0xa1,0x52,0xf6,0x4d,0x27,0xda,0x93,0x53,0xe5,0x48,0x86,0xb9,0x7d,0xe2,0x8f,0x3b,0xfa,0xb7,0x91,0x22,0x5b,0x59,0x15,0x82,0x35,0xf5,0x30,0x1f,0x04,0xdc,0x75,
Key=Green 0xab,0xd7,0x34,0x63,0xae,0x19,0x52,0x00,0xb8,0x84,0xa3,0x44,0xbd,0x11,0x9f,0x72,0xe0,0x04,0x68,0x4f,0xc4,0x89,0x3b,0x20,0x8d,0x2a,0xa7,0x07,0x32,0x3b,0x5e,0x74,

Quando il database viene crittografato, le sue pagine di intestazione rimangono non crittografate per memorizzare informazioni sul plugin di crittografia e il nome della chiave, e potete vedere queste informazioni con il comando “gstat -h nomedatabase”:

Code
Database header page information:
....
Creation date    Jan 11, 2017 15:12:20
Attributes       force write, encrypted, plugin DBCRYPT

Variable header data:
 Crypt checksum: MUB2NTJqchh9RshmP6xFAiIc2iI=
 Key hash:       ask88tfWbinvC6b1JvS9Mfuh47c=
 Encryption key name:    RED
 Sweep interval:         0
*END*

DbCrypt può elaborare pagine per diversi database e diverse chiavi:

Figura 7. Chiavi multiple per database multipli sullo stesso server (cioè, istanza Firebird)

Scelta della chiave corretta

Spesso gli sviluppatori fanno la domanda “Come fa il plugin a riconoscere quale chiave è per quale database?” La risposta è abbastanza semplice: tramite il nome della chiave, che è memorizzato nella pagina di intestazione del database.

Meno frequente, ma comunque importante, è la domanda: cosa succede se il nome della chiave è come registrato nell’intestazione, ma il valore della chiave è diverso? Per prevenire errori di lettura delle pagine dovuti a una chiave sbagliata, il plugin DbCrypt memorizza una sequenza di test crittografata (cifre 0…F) nell’intestazione, e quando la chiave viene attivata, il plugin tenta di crittografare i dati di esempio con la chiave e confronta il suo hash con il risultato memorizzato, per garantire che il valore della chiave passato sia effettivamente corretto per quel particolare database.

L’approccio in cui il plugin di crittografia legge le chiavi direttamente è semplice e vantaggioso per il debug, i test delle prestazioni, ecc., perché implementa la crittografia in modo trasparente: cioè, le applicazioni client e gli strumenti per sviluppatori non sanno che il database è crittografato.

Tuttavia, in realtà, dobbiamo limitare l’accesso delle applicazioni al database: solo l’applicazione client che ha una chiave dovrebbe essere in grado di connettersi al database crittografato.

Per questo, abbiamo bisogno del plugin KeyHolder, per ottenere la chiave dall’applicazione client (che di solito è su un altro computer) tramite il protocollo di rete Firebird.

2.3. Come proteggere il trasferimento delle chiavi?

È possibile che vogliamo proteggere il database nella situazione in cui il cliente decide di ottenere accesso diretto al database crittografato, bypassando le applicazioni autorizzate (molti fornitori vogliono limitare i dati dall’accesso diretto, sia in sola lettura che in lettura-scrittura).

Ciò equivale alla situazione in cui un intruso ha accesso al server ma non ha le chiavi.

Consideriamo i seguenti scenari di attacco per intercettare le chiavi lato server:

  1. Quando l’intruso crea un plugin di crittografia falso (DBCrypt.dll) e lo posiziona sul server, e quando KeyHolder passa la chiave, il falso DbCrypt esegue il dump della chiave:

Figura 8. Attacco con falso DbCrypt.dll

  1. Quando l’intruso crea un file firebird.exe falso e ne esegue il dump:

Figura 9. Attacco con falso firebird.exe

Per proteggersi da tali attacchi, una buona implementazione dei plugin di crittografia e di gestione delle chiavi deve proteggere lo scambio delle chiavi.

Lo scambio delle chiavi può essere protetto con crittografia asimmetrica tramite una coppia di chiavi pubblica/privata.

Queste chiavi vengono generate durante il processo di build e integrate per la coppia specifica di plugin di crittografia e di gestione delle chiavi. Per la migliore protezione, è necessario utilizzare coppie appositamente costruite di DbCrypt/KeyHolder.

Quando DbCrypt e KeyHolder scambiano le chiavi, utilizzano il seguente protocollo (è semplificato, ma l’idea è chiara, credo):

Code
DbCrypt → KeyHolder:
	Dammi la chiave del database con questo salt
KeyHolder:
	Crittografa DbKey con la chiave pubblica usando il salt di DbCrypt
	Trasferisce DbKey crittografata a DbCrypt
DbCrypt:
	Decrittografa DbKey con la chiave privata
	Valida la correttezza del salt
	Pronto a lavorare

Più o meno lo stesso protocollo viene utilizzato per lo scambio di chiavi tra istanze di KeyHolder e per lo scambio di chiavi tra un’applicazione client e KeyHolder.

Si noti che la crittografia e la correttezza delle chiavi trasferite dipendono dall’implementazione del plugin; il motore Firebird fornisce solo un servizio di trasferimento di base a basso livello “invia N byte da questa istanza del plugin a quell’istanza del plugin”.

Riepilogo per la parte server della crittografia

  • La crittografia/decrittografia viene eseguita dal plugin di crittografia del database (DbCrypt), pagina per pagina, durante lo scambio di dati tra la cache dei file del sistema operativo e la cache delle pagine di Firebird
  • La gestione delle chiavi può essere implementata in modo semplice quando DbCrypt legge le chiavi direttamente, ma di solito viene eseguita con il plugin di gestione delle chiavi (KeyHolder)

Ora scopriamo come le applicazioni client lavorano con database crittografati.

3. Come funziona la crittografia Firebird lato client

3.1. Applicazioni native

Per capire cosa succede quando un’applicazione client si connette a un database crittografato, consideriamo il normale processo di connessione a un database non crittografato per applicazioni native.

Si prega di notare: da qui in poi, “nativo” significa che tale applicazione stabilisce una connessione di rete con il server utilizzando fbclient.dll; di solito, tale applicazione è sviluppata in Delphi, C++, PHP. A differenza delle applicazioni native, Java e .NET implementano la propria versione del protocollo, che verranno considerate di seguito.

Processo di connessione:

  1. L’applicazione client carica la libreria client
  2. fbclient.dll - app native Windows
  3. libfbclient.so - app native Linux
  4. L’applicazione client avvia una connessione, inviando
  5. Nome utente, es. SYSDBA
  6. Password, es. masterkey
  7. Percorso/alias del database

Nel caso di un database crittografato, è necessario un passaggio aggiuntivo: è necessario passare il nome della chiave di crittografia e il suo valore.

È importante sottolineare che il passaggio della chiave deve essere effettuato prima della connessione regolare, poiché le pagine di dati con i metadati, inclusi il nome del proprietario del database, il charset, ecc., sono crittografate.

Quindi, questo ci porta a quanto segue:

  1. È necessario un roundtrip di rete aggiuntivo per passare la chiave prima della connessione regolare
  2. Il trasferimento della chiave dall’applicazione client a Firebird richiede codifica con l’uso di crittografia asimmetrica e implementazione di un’interfaccia di callback; può essere piuttosto complesso. Per semplificare questo compito, i fornitori di plugin forniscono un esempio del codice per la connessione o, come nel framework di plugin IBSurgeon, creano la libreria aggiuntiva fbcrypt.dll/libfbcrypt.so, che implementa un’interfaccia facile da usare e adatta per trasferire le chiavi dall’applicazione client.

Per connettere un’applicazione nativa (che utilizza fbclient.dll) a un database crittografato, è necessario eseguire 3 chiamate. Di seguito è riportato un esempio in Delphi (semplificato, senza gestione degli errori):

Nel gestore dell’evento BeforeConnect:

Code
fbcrypt_init(PAnsiChar(‘C:\Firebird30.bclient.dll’));
fbcrypt_key(‘RED’, ‘0xec,0xa1,0x52,0xf6,...’));
fbcrypt_callback(nil);

 // Poi connettersi come al solito
Database1.Active:=True;

Nella figura seguente è possibile vedere una panoramica del processo di connessione con un database crittografato nell’applicazione nativa:

Figura 10. Processo di connessione al database crittografato per applicazioni native

Che dire della sicurezza dei thread nel caso di applicazioni client multi-thread?

Permettetemi di ricordare alcuni punti generali sull’implementazione di applicazioni client multi-thread.

Dalla versione 2.5 di Firebird, più thread all’interno dell’applicazione possono utilizzare in sicurezza un singolo attachment al database, poiché tutta la sincronizzazione necessaria viene eseguita all’interno di fbclient.dll.

Tuttavia, in questo caso, i thread potranno lavorare con l’attachment solo uno alla volta.

Questo va bene per le applicazioni che non richiedono uno scambio di dati ad alte prestazioni con il database - se non è un problema attendere per eseguire una query SQL da un thread mentre un altro thread sta eseguendo un’altra SQL, è più semplice utilizzare un modello semplice in cui 1 attachment è condiviso tra più thread.

Se l’applicazione richiede di eseguire query SQL in parallelo (cioè, è un’applicazione client su vasta scala), è meglio utilizzare un thread separato per ogni connessione.

La situazione con lo scambio di chiavi per gli attachment ai database crittografati è un po’ più complessa.

Ad ogni attachment, la libreria client trasferisce le chiavi dal client, ma questo non è direttamente correlato ai thread nell’applicazione client; la situazione dipende dall’API utilizzata.

Come sapete, la libreria client Firebird dalla versione 3.0 offre 2 tipi di API: la nuova API orientata agli oggetti, basata sul concetto di provider, e la legacy isc_ API, implementata come soluzione alternativa per mantenere la compatibilità con i vecchi driver Firebird.

Se viene utilizzata la nuova API client orientata agli oggetti, è sufficiente creare il provider, fornirlo con le chiavi necessarie e poi utilizzarlo per i nuovi attachment.

Se viene utilizzata l’API client isc_, per ogni attachment la libreria client creerà il proprio provider temporaneo, che non è direttamente visibile o accessibile dall’utente finale.

In questo caso, la chiave viene trasferita esattamente dal thread in cui viene invocata isc_attach_database e viene utilizzato lo storage locale del thread per memorizzare tale chiave.

In pratica, poiché quasi tutte le librerie client utilizzano l’API isc_ (al momento, tra i driver popolari, solo il driver Python utilizza l’API OO), è necessario invocare fb_database_crypt_callback() in ogni thread che si connette al database crittografato.

Le chiamate di trasferimento delle chiavi (chiamate fbcrypt.dll nell’esempio FEPF) devono essere effettuate prima della connessione, nello stesso thread in cui verrà stabilita la connessione.

Quando lavoriamo con molti database (ad esempio, un server web SaaS con molti database clienti), è importante ricordare che ogni invocazione di fbcrypt_key() aggiunge una chiave allo storage di KeyHolder, associata alla connessione corrente.

I valori delle chiavi devono essere impostati prima della connessione; dopo l’attachment, il valore della chiave non può essere modificato.

In caso di distacco, le chiavi non vengono scaricate; verranno mantenute in memoria fino allo scaricamento di fbcrypt.dll.

3.2. Applicazioni Java

Il driver Java (JayBird) ha la propria implementazione (in puro Java) del protocollo di connessione Firebird. Jaybird 4 (e 3.0.4+) aggiunge il supporto per i callback di crittografia del database Firebird 3 nell’implementazione pura Java del protocollo versione 13.

Dalle note di rilascio di Jaybird 4:

" L’implementazione attuale è semplice e supporta solo la risposta con un valore statico da una proprietà di connessione. Si noti che una risposta con valore statico per la crittografia del database non è molto sicura, poiché può facilmente portare ad attacchi di replay o esposizione involontaria della chiave.

Le versioni future di Jaybird (probabilmente la 5) introdurranno il supporto per plugin di crittografia del database che richiedono un callback più complesso."

In pratica, ciò significa che dobbiamo impostare il valore per il callback di crittografia (normalmente, è una coppia nome chiave e valore chiave) nella proprietà di connessione dbCryptConfig.

Ad esempio:

Code
 edConnectionString.setText("jdbc:firebirdsql://localhost/g:/Databases/ODS12/crypt.fdb?lc_ctype=utf8&dbCryptConfig=MyKey:0xec,0xa1,0x52,0xf6,0x4d,0x27,0xda,0x93,0x53,0xe5,0x48,0x86,0xb9,0x7d,0xe2,0x8f,0x3b,0xfa,0xb7,0x91,0x22,0x5b,0x59,0x15,0x82,0x35,0xf5,0x30,0x1f,0x04,0xdc,0x75,");

È anche possibile specificare una stringa in base64 - dalle note di rilascio:

" Le stringhe con prefisso base64:: il resto della stringa viene decodificato come base64 in byte.

I caratteri di padding = sono opzionali, ma quando presenti devono essere validi (cioè: se si utilizza il padding, è necessario utilizzare il numero corretto di caratteri di padding per la lunghezza).

Quando il valore codificato in base64 contiene +, deve essere escapato come %2B nell’URL JDBC. Per compatibilità all’indietro con Jaybird 3, non possiamo passare alla variante URL-safe di base64."

Nell’implementazione IBSurgeon del plugin di gestione delle chiavi, tale trasmissione della chiave è considerata più o meno non sicura: se la crittografia del protocollo di rete non è abilitata ( a proposito, per abilitarla, impostare WireCrypt=Required in firebird.conf e non utilizzare l’autenticazione legacy), la chiave può essere facilmente individuata con un analizzatore di traffico di rete come WireShark; quindi, per abilitare la trasmissione delle chiavi in questo modo, è necessario impostare UnsafeClient=true in KeyHolder.conf del plugin di gestione delle chiavi IBSurgeon.

3.3 Applicazioni .NET

Il provider Firebird.NET implementa uno schema simile di scambio di chiavi per database crittografati e richiede anche di impostare il parametro UnsafeClient=true in KeyHolder.conf in FEPF.

Esempio .NET della stringa di connessione per database crittografati:

Code
string connectionString =
                "User=SYSDBA;" +
                "Password=masterkey;" +
                "Database=G:\\Databases\\ODS12.RYPT.FDB;" +
                "DataSource=localhost;" +
                "Port=3053;" +
                "Dialect=3;" +
                "Charset=NONE;" +
                "Role=;" +
                "Connection lifetime=15;" +
                "Pooling=true;" +
                "MinPoolSize=0;" +
                "MaxPoolSize=50;" +
                "Packet Size=8192;" +
                "ServerType=0;" +
                 "cryptkey = TXlLZXk6MHhlYywweG…...;";

Potete notare che la chiave di crittografia appare diversa rispetto all’esempio per applicazioni native e JayBird; questo perché è il risultato della trasformazione Base64, quindi per ottenere la chiave per applicazioni .NET o Java, è necessario calcolare il base64 dalla stringa:

“MyKey:0xec,0xa1,0x52,0xf6,0x4d,0x27,0xda,0x93,0x53,0xe5,0x48,0x86,0xb9,0x7d,0xe2,0x8f,0x3b,0xfa,0xb7,0x91,0x22,0x5b,0x59,0x15,0x82,0x35,0xf5,0x30,0x1f,0x04,0xdc,0x75,”

e utilizzarla come parametro per “cryptkey=xxx;” con “;” alla fine della stringa di connessione.

4. Installazione e configurazione

Per abilitare la crittografia del database e il plugin di gestione delle chiavi, è necessario specificare il nome del plugin di crittografia nel file di configurazione di Firebird firebird.conf:

Code
 KeyHolderPlugin = KeyHolder

Oppure, in alternativa, in databases.conf, per l’alias del database crittografato:

Code
myencrypted = C:\Temp\EMPLOYEE30.MPLOYEE30.FDB { KeyHolderPlugin = KeyHolder }

Quindi, è necessario verificare che tutti i file necessari per il plugin siano sul server.

L’esempio seguente è per FEPF di IBSurgeon, ma altri plugin sono più o meno simili:

In %FirebirdFolder$\plugins

Code
    • DbCrypt.dll
    • DbCrypt.conf
    • KeyHolder.dll
    • KeyHolder.conf - solo per modalità debug!

In %FirebirdFolder$

Code
    • fbcrypt.dll
    • libcrypto-1_1-x64.dll
    • libssl-1_1-x64.dll
    • firebird.msg

Dopo di che, possiamo eseguire la crittografia di test sul server, per questo, in isql:

Code
isql.exe localhost:C:\Temp\EMPLOYEE30.MPLOYEE30.FDB -user SYSDBA -pass masterkey
SQL>alter database encrypt with dbcrypt key red;
SQL> show database;
Database: localhost:C:\Temp\EMPLOYEE30.MPLOYEE30.FDB
….
ODS = 12.0
Database encrypted
Default Character set: NONE

Se sei su Linux, ricorda che le maiuscole/minuscole sono importanti, quindi il comando sarà:

Code
alter database encrypt with "DbCrypt" key Red;

Ora possiamo testare l’accesso del client al database crittografato. Per fare questo, rimuoveremo (o rinommeremo o modificheremo) il file di configurazione KeyHolder.conf e proveremo a connetterci al database crittografato con la semplice applicazione di test.

Per questo, dobbiamo inserire nella cartella con l’app client i seguenti file:

  • App demo da FEPF- CryptTest.exe (32bit)
  • File obbligatori:
    • fbclient.dll
    • fbcrypt.dll
    • libcrypto-1.1.dll
    • libssl-1.1-x64.dll
  • File opzionali:
    • firebird.conf
    • in plugins
    • ◦ KeyHolder.conf
    • ◦ keyhodler.dll

In alcune implementazioni dei plugin di gestione delle chiavi, è possibile caricare le chiavi nella libreria client (fbclient.dll), senza modificare il software client.

Ciò consente il funzionamento trasparente degli strumenti di sviluppo Firebird (come Firebird SQL Studio, DatabaseWorkbench, IBExpert, FlameRobin, RedExpert, ecc.) e l’uso trasparente degli strumenti da riga di comando Firebird (gfix.exe, nbackup.exe, ecc.).

5. Come monitorare l’avanzamento della crittografia

Firebird crittografa un database solo quando ha connessioni attive. Il processo di crittografia viene eseguito in un thread parallelo separato e, per database di grandi dimensioni, la crittografia completa può richiedere tempo significativo.

Per monitorare il processo di crittografia, esegui una query SQL da MON$:

Code
select mon$crypt_page * 100.0 / mon$pages as Percent from mon$database;
commit;

oppure esegui lo strumento gstat con l’opzione speciale:

Code
gstat -e dbname

Database "D:\ENCDB\TESTENCRYPT.FDB"
Gstat execution time Tue Mar 16 11:45:11 2021

Database header page information:
        Flags                   0
        Generation              10697
        System Change Number    3
        Page size               8192
        ODS version             12.0
        Oldest transaction      7053
        Oldest active           7054
        Oldest snapshot         7054
        Next transaction        7054
        Sequence number         0
        Next attachment ID      17834
        Implementation          HW=Intel/i386 little-endian OS=Windows CC=MSVC
        Shadow count            0
        Page buffers            0
        Next header page        0
        Database dialect        3
        Creation date           Oct 9, 2019 6:42:31
        Attributes              encrypted, plugin DBCRYPT

    Variable header data:
        Database backup GUID:   {866B4967-ED58-427E-A481-DB9206CEA2ED}
        Crypt checksum: MUB2NTJqchh9RshmP6xFAiIc2iI=
        Key hash:       ask88tfWbinvC6b1JvS9Mfuh47c=
        Encryption key name:    RED
        Database GUID:  {323FE494-1771-4608-E99D-C1B69C84578B}
        *END*

Data pages: total 105, encrypted 105, non-crypted 0
Index pages: total 95, encrypted 95, non-crypted 0
Blob pages: total 0, encrypted 0, non-crypted 0
Generator pages: total 1, encrypted 1, non-crypted 0
Gstat completion time Tue Mar 16 11:45:11 2021

Nota che l’esecuzione di gstat può essere un processo lungo.

  1. La crittografia del database Firebird è una potente funzionalità per proteggere le informazioni nei database da accessi non autorizzati.
  2. Il processo di crittografia richiede una libreria dinamica lato server - il plugin di crittografia (solitamente chiamato DbCrypt) e, nella stragrande maggioranza delle situazioni, il plugin di gestione delle chiavi (solitamente chiamato KeyHolder).
  3. L’implementazione sicura e affidabile dei plugin DbCrypt e KeyHolder dovrebbe essere fatta tenendo conto dei tipi di attacco più comuni.
  4. Per lavorare con il database crittografato, le applicazioni client devono trasferire la chiave di crittografia.
  5. L’installazione e la configurazione del plugin di crittografia lato server è banale, richiede 1 parametro in firebird.conf/databases.conf e diversi file.
  6. Il processo di crittografia può essere lungo, viene eseguito in un thread di background separato, l’avanzamento può essere monitorato con la chiamata MON$ o gstat.

Cosa succede dopo?

Stiamo lavorando a un test dettagliato delle prestazioni della crittografia del database Firebird. In generale, le prestazioni sono inferiori del 4-8%, ma dipende dall’hardware e dalle impostazioni di Firebird. Resta sintonizzato!

Contattaci:

Invia i tuoi suggerimenti, errori di battitura, errori, ecc. e qualsiasi domanda via email: [email protected]