SQL Server 2016 sempre crittografato: facile da implementare, difficile da decifrare

Pubblicato: 2022-03-11

I dati sono una risorsa chiave di qualsiasi azienda, in particolare i dati transazionali che detengono segreti aziendali come documenti finanziari o sanitari. I dati sono più vulnerabili in transito tra il server che li archivia e quel client che li richiede.

L'approccio standard per garantire la sicurezza consiste nel crittografare i dati sul server e utilizzare il protocollo HTTPS abilitato per SSL per proteggere i dati durante il trasporto. Tuttavia, se potessimo aumentare ulteriormente il livello di sicurezza, utilizzando HTTPS e inviando dati in formato crittografato sulla linea di comunicazione, solo per decrittografare i dati sui client che dispongono di certificati validi? Questo approccio renderebbe molto più difficile un tradizionale attacco man-in-the-middle (MITM).

Immagine di copertina della crittografia di SQL Server

La soluzione di Microsoft a questo problema è Always Encrypted, un modo per inviare dati crittografati attraverso la pipeline e decrittografarli solo da utenti con accesso a certificati validi. Quindi, anche se l'attaccante ottiene i dati, senza un certificato appropriato archiviato sulla macchina client, i dati sarebbero inutili.

Questo articolo descrive come configurare e utilizzare Always Encrypted e la lettura è consigliata a chiunque invii dati importanti tramite le linee di comunicazione pubbliche, anche se sono protette con SSL.

Il concetto alla base di Always Encrypted

Always Encrypted è una tecnologia di crittografia lato client introdotta da Microsoft con SQL Server 2016. Always Encrypted mantiene i dati crittografati automaticamente, non solo quando vengono scritti, ma anche quando vengono letti da un'applicazione approvata. A differenza di Transparent Data Encryption, che crittografa i dati e i file di registro sul disco in tempo reale ma consente la lettura dei dati da parte di qualsiasi applicazione che interroga i dati, Always Encrypted richiede che l'applicazione client utilizzi un driver abilitato per Always Encrypted per comunicare con il Banca dati. Utilizzando questo driver, l'applicazione trasferisce in modo sicuro i dati crittografati al database che può quindi essere decrittografato in seguito solo da un'applicazione che ha accesso alla chiave di crittografia. Qualsiasi altra applicazione che interroghi i dati può anche recuperare i valori crittografati, ma tale applicazione non può utilizzare i dati senza la chiave di crittografia, rendendo così i dati inutilizzabili. A causa di questa architettura di crittografia, l'istanza di SQL Server non vede mai la versione non crittografata dei dati.

Al momento, gli unici driver abilitati Always Encrypted sono il provider di dati .NET Framework per SQL Server, che richiede l'installazione di .NET Framework versione 4.6 sul computer client e il driver JDBC 6.0. Probabilmente cambierà nel tempo, ma questi sono i requisiti ufficiali di Always Encrypted a partire da aprile 2017.

Ma perché abbiamo bisogno di questa tecnologia? Ci sono un paio di buoni motivi per cui si dovrebbe usare Always Encrypted:

  • Sicurezza : i dati devono essere sempre protetti. Ora che SSL è stato compromesso, Always Encrypted colma il divario con un altro livello di protezione della pipeline di trasporto.
  • Supporto normativo — I dati devono essere crittografati e tenuti lontani da occhi indiscreti del DBA da parte di un numero sempre maggiore di normative di settore, principalmente nei settori finanziario e delle telecomunicazioni. Ciò è descritto nello standard PII ("Informazioni di identificazione personale") che afferma che elementi come numeri di carte di credito, numeri di previdenza sociale, nomi e indirizzi devono essere protetti, altrimenti il ​​proprietario dei dati può essere gravemente penalizzato.

Come utilizzare Always Encrypted

L'utilizzo di Always Encrypted richiede una piccola quantità di preparazione all'interno del server di database in cui vengono archiviate le tabelle crittografate. La preparazione è un processo in due fasi:

  • Creare la definizione della chiave master della colonna
  • Crea la chiave di crittografia della colonna

Chiave principale di colonna

Allora, cos'è una chiave master di colonna?

Chiave master della colonna in SQL Server 2016

La chiave master della colonna è un certificato che viene archiviato all'interno di un archivio certificati di Windows (che viene utilizzato nella demo come opzione di archiviazione dei certificati), un modulo di sicurezza hardware di terze parti (un nome generico per soluzioni di terze parti per l'installazione, la gestione e l'utilizzo certificati ) o Azure Key Vault (la soluzione basata su cloud di Microsoft per la gestione dei certificati).

L'applicazione che crittografa i dati utilizza la chiave master della colonna per proteggere varie chiavi di crittografia delle colonne che gestiscono la crittografia dei dati all'interno delle colonne di una tabella del database. L'utilizzo di archivi certificati da SQL Server, a volte denominati Enterprise Key Manager , richiede l'uso di SQL Server Enterprise Edition.

In questo articolo viene descritto l'utilizzo di un certificato autofirmato archiviato nell'archivio certificati Microsoft del sistema operativo Windows. Sebbene questo approccio non sia la configurazione ottimale, dimostra il concetto di Always Encrypted, ma va anche affermato che questo approccio non è accettabile per gli ambienti di produzione , dove la gestione dei certificati deve essere eseguita con account utente separati e protetti e, preferibilmente , su server separati.

È possibile creare una definizione di chiave master di colonna usando l'interfaccia grafica in SQL Server Management Studio (SSMS) o usando T-SQL. In SSMS, connettiti all'istanza del database di SQL Server 2016 in cui vuoi usare Always Encrypted per proteggere una tabella del database.

Creazione e utilizzo di chiavi master di colonna

In Esplora oggetti, passare prima al database, quindi a Sicurezza, quindi espandere la cartella Chiavi sempre crittografate per visualizzare le sue due sottocartelle, come mostrato nelle figure seguenti:

Crea una chiave in SSMS.

Crea una chiave in SSMS.

Aprire una nuova finestra di dialogo Chiave master di colonna.

Aprire una nuova finestra di dialogo Chiave master di colonna

Verificare l'esistenza della chiave nell'archivio certificati di Windows.

Verificare l'esistenza della chiave nell'archivio certificati di Windows

Per creare la chiave principale della colonna, fare clic con il pulsante destro del mouse sulla cartella Column Master Keys e selezionare New Column Master Key della colonna . Nella finestra di dialogo New Column Master Key digitare un nome per la chiave master della colonna, specificare se archiviare la chiave nell'archivio certificati dell'utente corrente o del computer locale o in Azure Key Vault, quindi selezionare un certificato nell'elenco. Se non sono presenti certificati o se si desidera utilizzare un nuovo certificato autofirmato, fare clic sul pulsante Generate Certificate , quindi fare clic su OK . Questo passaggio crea un certificato autofirmato e lo carica nell'archivio certificati dell'account utente corrente che esegue SSMS.

Nota: è necessario eseguire questi passaggi su un computer attendibile, ma non sul computer che ospita l'istanza di SQL Server. In questo modo, i dati rimangono protetti in SQL Server anche se il computer host è compromesso.

Quindi, dopo aver creato il certificato e averlo configurato come chiave master di colonna, è necessario esportarlo e distribuirlo a tutti i computer che ospitano i client che richiedono l'accesso ai dati. Se un'applicazione client è basata sul Web, è necessario caricare il certificato sul server Web. Se si tratta di un'applicazione installata sui computer degli utenti, è necessario distribuire il certificato individualmente sui computer di ciascun utente.

Puoi trovare le istruzioni applicabili per l'esportazione e l'importazione dei certificati per il tuo sistema operativo ai seguenti URL:

  • Esportazione di certificati
    • Windows 7 e Windows Server 2008 R2
    • Windows 8 e Windows Server 2012
    • Windows 8.1 e Windows Server 2012 R2
    • Windows 10 e Windows Server 2016
  • Importazione certificati
    • Windows 7 e Windows Server 2008 R2
    • Windows 8 e Windows Server 2012
    • Windows 8.1 e Windows Server 2012 R2
    • Windows 10 e Windows Server 2016

Quando si importano certificati nell'archivio certificati su computer con un'applicazione che crittografa e decrittografa i dati, è necessario importare i certificati nell'archivio certificati della macchina o nell'archivio certificati dell'account di dominio che esegue l'applicazione.

Chiave di crittografia della colonna

Dopo aver creato una chiave master di colonna, sei pronto per creare chiavi di crittografia per colonne specifiche. Il driver ADO.NET di SQL Server 2016 usa le chiavi di crittografia delle colonne per crittografare i dati prima di inviarli a SQL Server e per decrittografare i dati dopo averli recuperati dall'istanza di SQL Server 2016. Come con la chiave master della colonna, puoi creare chiavi di crittografia della colonna usando T-SQL o SSMS. Mentre le chiavi master delle colonne sono più facili da creare usando T-SQL, le chiavi di crittografia delle colonne sono più facili da creare usando SSMS.

Per creare una chiave di crittografia della colonna, utilizzare Object Explorer per connettersi all'istanza del database, passare al database, quindi a Security ed espandere la cartella Always Encrypted Keys . Fare clic con il pulsante destro del mouse su Column Encryption Keys e quindi selezionare New Column Encryption Key . Nella finestra di dialogo New Column Encryption Key , digitare un nome per la nuova chiave di crittografia, selezionare una Column Master Key Definition nell'elenco a discesa e quindi fare clic su OK . È ora possibile utilizzare la chiave di crittografia della colonna nella definizione di una nuova tabella.

Creazione della chiave di crittografia della colonna

Crittografia SQL: creazione della chiave di crittografia della colonna, immagine 1

Crittografia SQL: creazione della chiave di crittografia della colonna, immagine 2

Creazione di una tabella con valori crittografati

Dopo aver creato la definizione della chiave master della colonna e le chiavi di crittografia della colonna, è possibile creare una tabella per contenere i valori crittografati.

Prima di eseguire questa operazione, è necessario decidere quale tipo di crittografia utilizzare, quali colonne crittografare e se è possibile indicizzare queste colonne. Con la funzionalità Always Encrypted , si definiscono normalmente le dimensioni delle colonne e SQL Server modifica le dimensioni di archiviazione della colonna in base alle impostazioni di crittografia. Dopo aver creato la tabella, potrebbe essere necessario modificare l'applicazione per eseguire comandi su questa tabella utilizzando Always Encrypted .

Tipi di crittografia di SQL Server 2016

Prima di creare una tabella che contenga valori crittografati, è necessario decidere se ciascuna colonna deve essere crittografata o meno.

Innanzitutto, questa colonna verrà utilizzata per cercare valori o semplicemente per restituire quei valori?

Se la colonna verrà utilizzata per le ricerche, la colonna deve utilizzare un tipo di crittografia deterministico , che consente operazioni di uguaglianza. Tuttavia, esistono limitazioni alla ricerca di dati che sono stati crittografati utilizzando la funzionalità Always Encrypted . SQL Server 2016 supporta solo operazioni di uguaglianza, che includono joins equal to , not equal to , (che usano l'uguaglianza) e l'uso del valore nella clausola GROUP BY . Qualsiasi ricerca che utilizzi LIKE non è supportata. Inoltre, l'ordinamento dei dati crittografati tramite Always Encrypted deve essere eseguito a livello di applicazione, poiché SQL Server eseguirà l'ordinamento in base al valore crittografato anziché al valore decrittografato.

Se la colonna non verrà utilizzata per individuare i record, la colonna deve utilizzare il tipo di crittografia randomizzata. Questo tipo di crittografia è più sicuro, ma non supporta ricerche, join o operazioni di raggruppamento.

Creazione di una tabella con colonne crittografate

Quando si creano tabelle, si utilizza la normale sintassi CREATE TABLE con alcuni parametri aggiuntivi all'interno della definizione di colonna. Vengono utilizzati tre parametri all'interno della sintassi ENCRYPTED WITH per l'istruzione CREATE TABLE .

Il primo di questi è il parametro ENCRYPTION_TYPE , che accetta un valore di RANDOMIZED o DETERMINISTIC . Il secondo è il parametro ALGORITHM , che accetta solo un valore di RAEAD_AES_256_CBC_HMAC_SHA_256 . Il terzo parametro è COLUMN_ENCRYPTION_KEY , che è la chiave di crittografia utilizzata per crittografare il valore.

 CREATE TABLE [dbo].[Customers] ( [CustomerId] [int] IDENTITY(1,1), [TaxId] [varchar](11) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = YOUR_COLUMN_ENCRYPTION_KEY) NOT NULL, [FirstName] [nvarchar](50) NULL, [LastName] [nvarchar](50) NULL, [MiddleName] [nvarchar](50) NULL, [Address1] [nvarchar](50) NULL, [Address2] [nvarchar](50) NULL, [Address3] [nvarchar](50) NULL, [City] [nvarchar](50) NULL, [PostalCode] [nvarchar](10) NULL, [State] [char](2) NULL, [BirthDate] [date] ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = YOUR_COLUMN_ENCRYPTION_KEY) NOT NULL PRIMARY KEY CLUSTERED ([CustomerId] ASC) ON [PRIMARY] ); GO

Indicizzazione con Always Encrypted

Le colonne contenenti dati crittografati possono essere utilizzate come colonne chiave all'interno degli indici, a condizione che tali colonne siano crittografate utilizzando il tipo di crittografia DETERMINISTIC . Le colonne crittografate utilizzando il tipo di crittografia RANDOMIZED restituiscono un messaggio di errore quando si tenta di creare un indice su tali colonne. Le colonne crittografate utilizzando uno dei tipi di crittografia possono essere utilizzate come colonne INCLUDE all'interno di indici non cluster.

Poiché i valori crittografati possono essere indici, non sono necessarie ulteriori misure di ottimizzazione delle prestazioni per i valori crittografati con Always Encrypted oltre all'indicizzazione e all'ottimizzazione normalmente eseguite. Larghezza di banda di rete aggiuntiva e maggiore I/O sono gli unici effetti collaterali che derivano dalla maggiore dimensione dei valori restituiti.

Prestazioni sempre crittografate

Le prestazioni sono sempre un fattore chiave, soprattutto in questo caso, quando aggiungiamo un sovraccarico di crittografia al normale traffico del database. Il miglior sito per testare le prestazioni è SQL Performance, che ha testato l'esecuzione delle query e l'utilizzo del disco in vari scenari:

Test dei risultati delle prestazioni di SQL Server Always Encrypted.

Test dei risultati delle prestazioni di SQL Server Always Encrypted, immagine 1

Test dei risultati delle prestazioni di SQL Server Always Encrypted, immagine 2

Poiché c'è lavoro su CPU e disco rigido che deve essere eseguito con processi di crittografia e decrittografia, c'è un evidente impatto sulla quantità di spazio di archiviazione utilizzato e sulla durata delle query. Poiché ciò è influenzato dal tuo ambiente (CPU, RAM e funzionalità del disco), dovresti verificare se questo presenterà un problema in produzione.

Nota: nel caso in cui desideri saperne di più sull'ottimizzazione delle prestazioni di Microsoft SQL Server, consulta uno dei nostri articoli precedenti, Come ottimizzare Microsoft SQL Server per le prestazioni.

Modifiche all'applicazione

Cosa devi fare per implementare correttamente Always Encrypted nel codice legacy?

Uno degli aspetti positivi della funzionalità Always Encrypted di SQL Server 2016 è che le applicazioni che già utilizzano stored procedure, ORM o comandi T-SQL con parametri non devono richiedere modifiche all'applicazione per utilizzare Always Encrypted, a meno che non siano già in uso operazioni di non uguaglianza. Le applicazioni che creano istruzioni SQL come SQL dinamico all'interno dell'applicazione ed eseguono tali comandi direttamente sul database devono essere modificate per utilizzare la parametrizzazione delle loro query, una procedura consigliata per la sicurezza per tutte le applicazioni, prima che possano sfruttare la funzionalità Always Encrypted.

Un'altra modifica richiesta per far funzionare Always Encrypted è l'aggiunta di un attributo della stringa di connessione alla stringa di connessione dell'applicazione che si connette al database: Column Encryption Setting=enabled .

Con questa impostazione aggiunta alla stringa di connessione, il driver ADO.NET chiede a SQL Server se il comando in esecuzione include colonne crittografate e, in tal caso, quali colonne sono crittografate. Per le applicazioni a carico elevato, l'uso di questa impostazione potrebbe non essere la procedura consigliata, soprattutto se un'ampia percentuale di comandi in esecuzione non include valori crittografati.

Di conseguenza, .NET Framework fornisce un nuovo metodo sull'oggetto SqlConnection chiamato SqlCommandColumnEncryptionSetting , che ha tre possibili valori:

  • Disabled : non sono presenti colonne o parametri Always Encrypted da utilizzare per le query eseguite utilizzando questo oggetto di connessione.
  • Enabled : sono presenti colonne e/o parametri sempre crittografati in uso per le query eseguite utilizzando questo oggetto di connessione.
  • ResultSet : non sono presenti parametri Always Encrypted. Tuttavia, l'esecuzione di query utilizzando questo oggetto di connessione restituisce colonne crittografate utilizzando Always Encrypted.

Nota: tieni presente che l'uso di questo metodo può potenzialmente richiedere una quantità significativa di modifiche al codice dell'applicazione. Un approccio alternativo consiste nel refactoring dell'applicazione per utilizzare connessioni diverse.

Per le migliori prestazioni di SQL Server, è consigliabile richiedere solo i metadati su Always Encrypted per le query che utilizzano Always Encrypted. Ciò significa che nelle applicazioni per le quali un'ampia percentuale di query utilizza Always Encrypted, la stringa di connessione deve essere abilitata e le query specifiche all'interno dell'applicazione devono specificare SqlCommandColumnEncryptionSetting come Disabled . Per le applicazioni per le quali la maggior parte delle query non utilizza valori Always Encrypted, la stringa di connessione non deve essere abilitata e SqlCommandColumnEncryptionSetting deve essere impostato su Enabled o ResultSet in base alle esigenze per le query che utilizzano colonne Always Encryption. Nella maggior parte dei casi, le applicazioni sono in grado di abilitare semplicemente l'attributo della stringa di connessione e le prestazioni dell'applicazione rimarranno invariate durante l'utilizzo dei dati crittografati.

Vale sempre la pena crittografare?

Risposta breve? Sì, sicuramente!

Non solo aiuta a prevenire molti potenziali problemi di sicurezza e fornisce agli sviluppatori SQL funzionalità di sicurezza aggiuntive, ma rende anche il tuo sistema più conforme, il che è vitale in più settori, dalle telecomunicazioni al settore bancario e assicurativo. È inoltre importante notare che, dati i prerequisiti tecnici menzionati nell'articolo, Always Encrypted può essere implementato con modifiche minime dell'applicazione ai sistemi esistenti .

Sebbene tu possa utilizzare soluzioni personalizzate per ottenere lo stesso effetto, questa tecnologia è inclusa nella nuova versione di SQL Server e può essere utilizzata immediatamente. È anche importante notare che, poiché si tratta di una nuova tecnologia, ci sono ancora alcune limitazioni al suo utilizzo e aggiunge alcune esigenze hardware aggiuntive.

Tuttavia, a meno che non siano un problema per il tuo ambiente e tu abbia un'applicazione distribuita al di fuori della Intranet della tua azienda, non c'è praticamente alcun motivo per non utilizzare Always Encrypted.