Encryption at rest: il livello di default
In Azure, ogni servizio di storage (Azure Storage, dischi delle VM, Azure SQL Database, dedicated SQL pool di Synapse) cifra automaticamente i dati a riposo con Storage Service Encryption (SSE) basata su AES-256. È attiva by design, non disattivabile e trasparente: protegge dal furto fisico dei dischi o dall’accesso non autorizzato al layer di storage sottostante. Non richiede modifiche applicative né gestione di chiavi da parte tua nel caso base.
La domanda architetturale non è se cifrare a riposo, ma chi controlla la chiave:
- Service-managed key (Microsoft-managed): default, zero gestione, ma nessun controllo sul lifecycle.
- Customer-managed key (CMK / BYOK): chiave conservata in Azure Key Vault (o Key Vault Managed HSM per requisiti FIPS 140-2 Level 3). Ti dà rotazione, revoca e audit sotto il tuo controllo. Scegli CMK quando ci sono requisiti di compliance / separation of duties o la necessità di poter “spegnere” l’accesso ai dati revocando la chiave.
TDE — Transparent Data Encryption
TDE cifra a riposo i file di database, i log e i backup di Azure SQL Database, SQL Managed Instance e dedicated SQL pool. È transparent: la cifratura/decifratura avviene a livello di pagina di I/O, quindi l’applicazione e le query non cambiano e non c’è impatto sulla logica SQL.
Meccanica delle chiavi:
- Un Database Encryption Key (DEK) simmetrico cifra i dati.
- Il DEK è protetto da un TDE protector, che può essere service-managed oppure customer-managed (BYOK) in Key Vault.
Su Azure SQL e SQL MI il TDE è abilitato per default. Su dedicated SQL pool va attivato esplicitamente (portale o ALTER DATABASE ... SET ENCRYPTION ON). Usa il TDE protector in Key Vault quando devi soddisfare audit sul lifecycle della chiave; ricorda che revocare quella chiave rende il database inaccessibile — potente ma pericoloso.
Il limite concettuale chiave: TDE protegge i dati “at rest”, non i dati “in use”. Chi ha permessi di query legge i dati in chiaro, perché la decifratura avviene prima che la riga arrivi al client.
Always Encrypted — cifratura lato client per colonne sensibili
Always Encrypted risolve proprio quel limite. Cifra singole colonne (es. codice fiscale, numero di carta) client-side: i dati entrano ed escono cifrati, e il motore SQL non vede mai il valore in chiaro. Questo separa chi amministra il database da chi può vedere i dati sensibili — protegge quindi anche da DBA, operatori cloud o attacchi con credenziali privilegiate.
Due chiavi:
- Column Encryption Key (CEK): cifra i dati.
- Column Master Key (CMK): protegge i CEK, custodita fuori dal database (Key Vault, Windows Certificate Store, ecc.). Il driver client la usa per decifrare.
Due modalità, scelta cruciale d’esame:
- Deterministic: lo stesso plaintext produce sempre lo stesso ciphertext. Consente equality lookup, join, group by, indici sulla colonna. Prezzo: pattern ripetuti sono analizzabili → più debole su colonne a bassa cardinalità.
- Randomized: più sicura (nessun pattern), ma impedisce qualsiasi operazione lato server — niente WHERE, JOIN, ORDER BY, indice. Usala per colonne che leggi/scrivi ma non filtri.
Always Encrypted with secure enclaves attenua i limiti abilitando range query e pattern matching su colonne randomized, sfruttando una enclave protetta lato server.
Come combinarle
Non sono alternative: TDE + Always Encrypted lavorano insieme. TDE dà la baseline at-rest trasparente sull’intero database; Always Encrypted aggiunge protezione end-to-end mirata sulle colonne più sensibili, sottraendole anche a chi ha accesso in query. La cifratura di default dello storage resta sotto tutto.
Trappole tipiche d’esame
- “Proteggere i dati anche da un DBA con permessi di lettura sulle query” → Always Encrypted (client-side), non TDE. TDE lascia i dati in chiaro a chiunque interroghi il database.
- “Cifrare a riposo l’intero dedicated SQL pool senza modifiche applicative” → TDE (transparent). Ricorda che sul dedicated SQL pool va abilitato esplicitamente, mentre su Azure SQL è già attivo.
- “Colonna cifrata su cui servono WHERE di uguaglianza, JOIN o indice” → Always Encrypted deterministic. Se lo scenario richiede massima sicurezza senza operazioni server-side → randomized (che però blocca filtri/join).
- “Serve controllo su rotazione/revoca della chiave e audit per compliance” → customer-managed key (BYOK) in Azure Key Vault, non service-managed.
- “Range query o LIKE su colonna randomized” → serve Always Encrypted with secure enclaves; senza enclave quelle operazioni falliscono.