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.