S
Home Databases ยท Updated 2026-07-23

Database Encryption in SQL Server

SQL Server Hardening covers Transparent Data Encryption (TDE) briefly as one control among many. This article goes deeper on encryption specifically โ€” both whole-database encryption at rest (TDE) and column-level encryption (native cell-level encryption and Always Encrypted) โ€” because they solve different threat models and are frequently confused with each other. TDE protects against someone stealing a disk or backup file; it does nothing against a DBA, a compromised application account, or an attacker with a live authenticated connection reading plaintext through ordinary queries. Column-level encryption, done right, protects against exactly that. Most production systems handling sensitive data need both, applied to different things.

Scope: SQL Server 2016โ€“2022, on-premises and IaaS. Azure SQL Database/Managed Instance support the same features with some PaaS-specific management differences (e.g., TDE with customer-managed keys via Azure Key Vault), noted where relevant.


1. The SQL Server Encryption Hierarchy

Both TDE and column-level encryption sit on top of the same underlying key hierarchy โ€” understanding it once makes every feature built on it easier to reason about:

Windows DPAPI (protects the instance's credentials)
   โ””โ”€โ”€ Service Master Key (SMK) โ€” one per instance, auto-created, never leaves the instance
        โ””โ”€โ”€ Database Master Key (DMK) โ€” one per database, created explicitly by an admin
             โ””โ”€โ”€ Certificates / Asymmetric Keys โ€” protected by the DMK
                  โ””โ”€โ”€ Symmetric Keys / Database Encryption Key (DEK) โ€” protected by a cert/asym key
                       โ””โ”€โ”€ Actual data (TDE's DEK, or a column's ciphertext)

Every layer is encrypted by the layer above it. Losing a certificate or key without a backup means everything it protects โ€” an entire TDE-encrypted database, or a set of encrypted columns โ€” becomes permanently unrecoverable, not just inaccessible. This is the single most common self-inflicted encryption incident: enabling encryption without immediately backing up the certificate/key that makes it reversible.


2. Transparent Data Encryption (TDE) โ€” Whole-Database Encryption at Rest

What TDE Actually Protects

TDE encrypts the physical data (.mdf), log (.ldf), and tempdb files, plus backups, at the storage layer. It's called "transparent" because no application changes are needed โ€” SQL Server decrypts pages on the fly for any authenticated connection. That transparency is also its limitation:

Protects against Does NOT protect against
Stolen disk, SAN snapshot, or VM image A DBA or any authenticated user running SELECT
A .bak file copied off a backup share A compromised application account with normal query access
Physical media disposal without wiping SQL injection reading data through the live application
Attaching a detached .mdf to another instance Data in memory or data in transit (separate controls)

Setup

-- 1. Service-level master key and certificate (once per instance/database)
USE master;
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<strong-unique-password>';
CREATE CERTIFICATE TDE_Cert WITH SUBJECT = 'TDE Certificate';

-- 2. Database encryption key, protected by that certificate
USE [YourDatabase];
CREATE DATABASE ENCRYPTION KEY
    WITH ALGORITHM = AES_256
    ENCRYPTION BY SERVER CERTIFICATE TDE_Cert;

-- 3. Turn it on
ALTER DATABASE [YourDatabase] SET ENCRYPTION ON;

Encryption of existing data happens as a background scan โ€” the database remains online and usable throughout, but avoid triggering it during peak load on very large databases. Monitor progress and current state:

SELECT db_name(database_id) AS db_name, encryption_state, percent_complete, encryptor_type
FROM sys.dm_database_encryption_keys;

encryption_state: 0 = no key present, 1 = unencrypted, 2 = encryption in progress, 3 = encrypted, 4 = key change in progress, 5 = decryption in progress, 6 = protection change in progress (e.g., swapping the protecting certificate).

Certificate and Key Management โ€” the Part People Skip

-- Immediately after creating the certificate -- do not skip this step
BACKUP CERTIFICATE TDE_Cert TO FILE = 'D:\Secure\TDE_Cert.cer'
WITH PRIVATE KEY (
    FILE = 'D:\Secure\TDE_Cert.pvk',
    ENCRYPTION BY PASSWORD = '<different-strong-password>'
);
  • Store the certificate and private key backup separately from database backups, on access-controlled storage, and vault the password.
  • Without this backup, restoring a TDE-encrypted backup to another server, or recovering from a corrupted master database, is impossible โ€” not "difficult," impossible. TDE is deliberately designed so there's no bypass.
  • Rotate the DEK periodically per policy: ALTER DATABASE [YourDatabase] SET ENCRYPTION KEY ... REGENERATE; re-encrypts with a new key without a full offline re-encryption cycle for the certificate layer.
  • For higher-assurance environments, use Extensible Key Management (EKM) to root the TDE certificate in an external HSM rather than SQL Server's own key store โ€” Azure SQL's TDE with a customer-managed key (Azure Key Vault) is the PaaS equivalent of this pattern.

Always On / Replication Considerations

Every secondary replica in an Availability Group, and every subscriber in log shipping/replication involving a TDE-encrypted database, needs the same certificate and private key imported before it can host that database. This is a common cause of failed AG joins โ€” plan certificate distribution before enabling TDE on a database that's already part of a topology.


3. Cell-Level Encryption โ€” Native T-SQL Column Encryption

Before Always Encrypted existed (pre-2016), SQL Server's native way to encrypt specific columns was via symmetric/asymmetric keys and the ENCRYPTBYKEY/DECRYPTBYKEY (or ENCRYPTBYCERT/ENCRYPTBYASYMKEY) T-SQL functions. It's still valid, still supported, and still occasionally the right tool โ€” mainly for legacy applications that can't adopt an Always Encrypted-aware driver.

-- Setup: master key โ†’ certificate โ†’ symmetric key
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<strong-password>';
CREATE CERTIFICATE Col_Cert WITH SUBJECT = 'Column Encryption Certificate';
CREATE SYMMETRIC KEY Col_Key
    WITH ALGORITHM = AES_256
    ENCRYPTION BY CERTIFICATE Col_Cert;

-- Column must be varbinary -- it stores ciphertext, not the original type
ALTER TABLE dbo.Customers ADD SSN_Encrypted varbinary(256);

-- Write: open the key for the session, then encrypt
OPEN SYMMETRIC KEY Col_Key DECRYPTION BY CERTIFICATE Col_Cert;
UPDATE dbo.Customers
SET SSN_Encrypted = ENCRYPTBYKEY(KEY_GUID('Col_Key'), SSN)
WHERE SSN_Encrypted IS NULL;
CLOSE SYMMETRIC KEY Col_Key;

-- Read: open the key, then decrypt
OPEN SYMMETRIC KEY Col_Key DECRYPTION BY CERTIFICATE Col_Cert;
SELECT CustomerID, CONVERT(varchar(11), DECRYPTBYKEY(SSN_Encrypted)) AS SSN
FROM dbo.Customers;
CLOSE SYMMETRIC KEY Col_Key;

What This Does and Doesn't Buy You

  • The column is genuinely ciphertext at rest and in backups.
  • It does not meaningfully protect against a DBA. Access to decrypt is gated by a database permission (GRANT VIEW DEFINITION / control over the certificate and key), and anyone with sysadmin or db_owner can grant themselves that permission, or simply take a certificate backup and decrypt offline. This is the key distinction from Always Encrypted below.
  • You lose native indexing, sorting, and equality search on the plaintext value โ€” the column is varbinary, so any lookup requires decrypting rows (expensive at scale) or maintaining a separate deterministic hash/HMAC column purely for lookup purposes.
  • Application/T-SQL changes are required throughout โ€” this is not transparent the way TDE is.

4. Always Encrypted โ€” Client-Side Column Encryption

Always Encrypted's core architectural difference: encryption and decryption happen in the client driver, not in the database engine. Plaintext, and the keys that would decrypt it, are never present inside SQL Server at all โ€” not in memory, not in query plans, not in backups, not visible to a sysadmin running SELECT *. This is the feature that actually protects sensitive columns from a DBA or from an attacker who has fully compromised the SQL Server instance itself.

Key Architecture

Key What It Does Where It Lives
Column Master Key (CMK) Protects the CEK below Outside SQL Server entirely โ€” Windows Certificate Store, Azure Key Vault, or an HSM
Column Encryption Key (CEK) Actually encrypts column data Encrypted by the CMK, stored (still encrypted) in SQL Server's metadata only

Because the CMK never enters SQL Server, SQL Server can never decrypt the CEK, and can therefore never see plaintext. This isn't a permission that can be misconfigured away โ€” it's an architectural guarantee as long as the CMK stays outside the instance.

Deterministic vs. Randomized Encryption

Deterministic Randomized
Same plaintext โ†’ Same ciphertext every time Different ciphertext every time
Supports equality (WHERE col = @x), JOIN, GROUP BY, indexing Yes No (without a secure enclave)
Supports range queries, LIKE, sorting No No (without a secure enclave)
Leaks pattern information Yes โ€” repeated values are visible as repeated ciphertext, enabling frequency analysis on low-cardinality columns No
Typical use Columns you need to look up by (e.g., a national ID used as a search key) Columns you only ever retrieve, never filter on (e.g., a stored payment token)

For a low-cardinality column (a boolean, a small enum), deterministic encryption can leak the distribution of values through ciphertext frequency alone โ€” think carefully before using deterministic encryption on anything with few possible values.

Setup

-- Typically done via SSMS's Always Encrypted wizard or PowerShell, shown here as T-SQL for clarity
CREATE COLUMN MASTER KEY CMK_Customer
WITH (
    KEY_STORE_PROVIDER_NAME = 'AZURE_KEY_VAULT',   -- or 'MSSQL_CERTIFICATE_STORE' on-prem
    KEY_PATH = 'https://your-vault.vault.azure.net/keys/CMK1/<version>'
);

CREATE COLUMN ENCRYPTION KEY CEK_Customer
WITH VALUES (
    COLUMN_MASTER_KEY = CMK_Customer,
    ALGORITHM = 'RSA_OAEP',
    ENCRYPTED_VALUE = 0x...   -- generated by the tooling, not hand-typed
);

ALTER TABLE dbo.Customers
ALTER COLUMN NationalID varchar(11)
COLLATE Latin1_General_BIN2   -- required collation for deterministic encryption on string columns
ENCRYPTED WITH (
    COLUMN_ENCRYPTION_KEY = CEK_Customer,
    ENCRYPTION_TYPE = DETERMINISTIC,
    ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256'
);

Application Requirements

Unlike TDE, this is not transparent to existing applications. The connection string must explicitly opt in:

Column Encryption Setting=Enabled;

And the client driver must support Always Encrypted: modern ADO.NET, JDBC 6.0+, ODBC 17.1+, and current versions of common ORMs. An application connecting without an Always Encrypted-aware driver simply receives ciphertext varbinary blobs and cannot use the data at all โ€” there's no silent fallback to plaintext, which is the correct failure mode for a security control but does mean every consumer of that data needs to be inventoried and updated before rollout.

Secure Enclaves (SQL Server 2019+)

Secure enclaves narrow the gap between deterministic's query flexibility and randomized's stronger security: computations (range queries, LIKE, in-place re-encryption) can run against randomized-encrypted data inside a hardware-protected memory enclave (Intel SGX) on the server โ€” a region that's isolated even from the OS and hypervisor, and that an attestation service verifies before the client will send key material into it. This requires compatible hardware/VM SKUs and an attestation service, so it's a deliberate infrastructure investment, not a checkbox โ€” but it's the way to get richer query support without falling back to deterministic encryption's pattern-leakage tradeoff.


5. Choosing Between the Three

Dimension TDE Cell-Level (ENCRYPTBYKEY) Always Encrypted
Protects against stolen disk/backup Yes Yes Yes
Protects against a DBA/sysadmin viewing plaintext live No No โ€” key access is a grantable permission Yes โ€” keys never present in SQL Server
Query support on the protected data Full, transparent None natively Deterministic: equality only. Randomized: none without an enclave
Application changes required None T-SQL/app rewrite to call encrypt/decrypt functions Driver + connection string change; column provisioning
Best fit Baseline at-rest protection for an entire database Legacy apps needing app-controlled column protection without AE tooling Regulated/high-sensitivity columns (national IDs, payment data, health records) needing genuine insider-threat protection

These aren't mutually exclusive โ€” a common, sound pattern is TDE on the whole database as a baseline, plus Always Encrypted on the specific columns that need DBA-proof protection.


6. Key and Certificate Management Practices

Applies across all three mechanisms:

  • Back up the Service Master Key, every Database Master Key, and every certificate immediately after creation โ€” before you need them, not after a disaster.
  • Store key/certificate backups separately from database backups, encrypt the backup files themselves, and keep the password in a vault, not a shared drive next to the backup.
  • Rotate keys and certificates on a defined schedule, and immediately on any suspected compromise or when a DBA with direct access to key material leaves the organization.
  • For Always Encrypted, prefer Azure Key Vault or an on-prem HSM over the Windows Certificate Store for the CMK in production โ€” a cert-store-based CMK is only as protected as that one machine, and doesn't scale cleanly to multiple app servers needing access.
  • Consider EKM to root TDE's certificate in a physical/cloud HSM instead of SQL Server's own encryption hierarchy, removing SQL Server itself as the ultimate trust anchor.

7. Monitoring and Verification

Check Query / Location
TDE state per database sys.dm_database_encryption_keys
Always Encrypted key inventory sys.column_encryption_keys, sys.column_master_keys
Cell-level / hierarchy key inventory sys.symmetric_keys, sys.certificates, sys.asymmetric_keys
Certificate expiration SELECT name, expiry_date FROM sys.certificates;
Who can open a cell-level symmetric key Permission grants on the key/certificate โ€” review regularly

Alert on: TDE unexpectedly disabled on a database that should have it, a certificate approaching expiry, a new Column Master Key or Column Encryption Key introduced outside a change window, and permission grants on cell-level encryption keys/certificates to unexpected principals.


Implementation Checklist

Item Priority
TDE enabled on every database holding sensitive data High
TDE certificate and private key backed up immediately, stored separately from DB backups Critical
TDE certificate distributed to every AG replica / log-shipping subscriber before joining Critical
Backups encrypted independently of TDE state High
Always Encrypted (or cell-level encryption, for legacy apps) applied to columns requiring insider-threat protection High
Deterministic encryption reserved for columns that genuinely need equality lookups; randomized used elsewhere Medium
Column Master Key stored in Key Vault/HSM, not just the local certificate store, for production High
Application drivers confirmed Always Encrypted-aware before rollout; no silent plaintext fallback assumed Critical
Cell-level key/certificate permission grants reviewed on a schedule Medium
Key/certificate rotation schedule defined and followed Medium
Encryption state and key inventory monitored, with alerting on drift High

NIST SP 800-53 Rev. 5 Control Mapping

Control Title Applied Here
SC-28 Protection of Information at Rest TDE, cell-level encryption, Always Encrypted
SC-28(1) Cryptographic Protection Algorithm choices (AES-256, AEAD_AES_256_CBC_HMAC_SHA_256)
SC-12 Cryptographic Key Establishment and Management Encryption hierarchy, CMK/CEK separation, backup/rotation practices
SC-13 Cryptographic Protection Overall use of FIPS-validated algorithms where required
AC-6 Least Privilege Always Encrypted's architectural removal of DBA plaintext access
AU-2 / AU-6 Audit Events / Audit Review Monitoring key inventory and permission grants for drift

References

The Security Architecture Site โ€” for internal reference use. Back to contents