MSSQL Encryption

TDE vs "Always Encrypted"

Transparent Data Encryption (TDE)

Check

Check existing certificates and encrypted databases

use [master]

go


/* Symmetric Keys */

SELECT * 

  FROM sys.symmetric_keys


/* Encrypted Databases */

SELECT db.name,

       db.is_encrypted,

       dm.encryption_state,

       dm.percent_complete,

       dm.key_algorithm,

       dm.key_length

  FROM sys.databases db

  LEFT OUTER JOIN sys.dm_database_encryption_keys dm ON db.database_id = dm.database_id

 ORDER BY name

/* Certificates */

SELECT * 

  FROM sys.certificates


/* Encryption State *//* is_encrypted = 1 means the database was explicitly encrypted (tempdb is implicitly encrypted so will show as 0) *//* encryption_state = 3 means the database is encrypted *//* percent_complete = 0 means encryption process is complete */

SELECT DB_NAME(database_id) AS dbName, * 

  FROM sys.dm_database_encryption_keys 

 WHERE encryption_state = 3 

 ORDER BY 1


/* Show certificate used to encrypt */

SELECT DB_NAME(dek.database_id) as dbName,

       c.name AS CertName,

       dek.set_date,

       c.expiry_date,

       DATEADD(year, 2, c.start_date) AS [Two Years After Create]

  FROM sys.dm_database_encryption_keys dek

  LEFT JOIN sys.certificates c ON dek.encryptor_thumbprint = c.thumbprint

ORDER BY 1


NOTE: ALGORITHM_DESC should be AES_256. It is acceptable for it to be AES_192 or AES_128. Other values should be addressed if possible.Note also that in SQL2008R2 the ##MS_DatabaseMasterKey## will show an algorithm_desc of TRIPLE_DES.See: https://docs.microsoft.com/en-us/sql/t-sql/statements/create-master-key-transact-sql"When it is created, the master key is encrypted by using the AES_256 algorithm and a user-supplied password. In SQL Server 2008 and SQL Server 2008 R2, the Triple DES algorithm is used."

Encryption State

SELECT DB_NAME(database_id) AS dbName, encryption_state

  FROM sys.dm_database_encryption_keys 

 ORDER BY 1

Rotate Encryption Keys

Create New Certificate

USE master

go

CREATE CERTIFICATE newTDECert WITH SUBJECT = 'NEW TDE Certificate', expiry_date = '2020-06-19' /* 2 years from today */

go

BACKUP CERTIFICATE newTDECert 

TO FILE = 'G:\SQLBackup\newTDECert.cer.bak'

WITH PRIVATE KEY

(FILE = 'G:\SQLBackup\newTDECert_Key.pvk.bak',

ENCRYPTION BY PASSWORD = 'Use_Strong_Password_Neccessary_To_Restore_Later')

NOTE: Setting an Expiry Date will NOT stop the database working beyond that date. BUT, note that it is possible for an application to check the expiry date and take an action, such as blocking access, if it finds the expiry date has passed.

Rotate TDE Encryption Key

/* work in context of encrypted database */

USE [WorkspaceDB]

go


ALTER DATABASE ENCRYPTION KEY

    ENCRYPTION BY SERVER CERTIFICATE newTDECert

Re run Check scripts above to confirm rotation has been successful

Encryption Key Backups

Drop Old Certificate

USE master

go

DROP CERTIFICATE ExpiredTDECert

Encrypt Database

Create master key and certificate (if does not exist)

USE [MASTER]

go

--Service Master Key is backed up with master database but we can also make separate backup

BACKUP SERVICE MASTER KEY

TO FILE = 'F:\SQLBackup\service_master_key.bak'

ENCRYPTION BY PASSWORD = 'Use_Strong_Password12#34_a'

go

CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Use_Strong_Password12#34_a'

GO

--Database Master Key is backed up with database (master if using TDE) but we can also make its backup

BACKUP MASTER KEY

TO FILE = 'F:\SQLBackup\master_key.bak'

ENCRYPTION BY PASSWORD = 'Use_Strong_Password12#34_a'

go

CREATE CERTIFICATE TDECert1 WITH SUBJECT = 'TDE Certificate', expiry_date = '2020-06-19' /* 2 years from today */

Create key in your database and make backup of certificate and key


NOTE: Algorithm should be AES_256. Use AES_128 or AES_192 only if justified. Use of TRIPLE_DES or TRIPLE_DES_3KEY should be avoided. Do NOT use DES, DESX, RC2, RC4 or RC4_128.

use [WorkspaceDB]

go

CREATE DATABASE ENCRYPTION KEY WITH 

ALGORITHM = AES_256 ENCRYPTION BY 

SERVER CERTIFICATE TDECert1

/*

You will get warning: 

The certificate used for encrypting the database encryption key has not been backed up. 

You should immediately back up the certificate and the private key associated with the certificate. 

If the certificate ever becomes unavailable or if you must restore or attach the database on another server, 

you must have backups of both the certificate and the private key or you will not be able to open the database.

*/

go

USE [master]

GO 

BACKUP CERTIFICATE TDECert1 

TO FILE = 'F:\SQLBackup\certificate_TDECert1.cer.bak'

WITH PRIVATE KEY

(FILE = 'F:\SQLBackup\certificate_TDECert1_Key.pvk.bak',

ENCRYPTION BY PASSWORD = 'Use_Strong_Password_Neccessary_To_Restore_Later')

Encrypt your database

USE WorkspaceDB

go

/* that will start encryption in the background */

ALTER DATABASE  WorkspaceDB SET ENCRYPTION ON 

go

/* 

Database become encrypted when is on the list returned by following command, database can be used form DML during that process 

Encryption_state = 3 is encrypted

*/

SELECT DB_NAME(database_id) as dbName, * FROM sys.dm_database_encryption_keys WHERE encryption_state = 3 

Encryption Key Backups

Decrypt Database


Caution: for MS SQL 2008 and 2008R2 see links available in 'Other link' section. For other MS SQL versions perform tests before you decide to drop master key and certificate

Following steps have been successfully performed on MS SQL 2008R2 SP3

use master

go

select * from sys.symmetric_keys

select * from sys.databases where is_encrypted=1

SELECT * FROM sys.certificates

/* encryption_state = 3 is encrypted */

SELECT DB_NAME(database_id) as dbName, * FROM sys.dm_database_encryption_keys WHERE encryption_state = 3

--work in context of database you are going to decrypt

USE WorkspaceDB

go

ALTER DATABASE WorkspaceDB SET ENCRYPTION OFF

go

/* 

Database become decrypted when is on the list returned by following command, database can be used form DML during that process 

Encryption_state = 1 means not encrypted

*/

SELECT DB_NAME(database_id) as dbName, * FROM sys.dm_database_encryption_keys WHERE encryption_state = 1

go

--work in context of database you are going to decrypt

USE WorkspaceDB  

go

/* execute only if above command returns encryption_state = 1 - non encrypted  */

DROP DATABASE ENCRYPTION KEY

NOTE: Perform following steps only if restore to different server was successful or/and you have backup of certificate 

USE master

go

DROP CERTIFICATE TDECert1

go

DROP MASTER KEY

Backup/Restore

Asymmetric Keys

If asymmetric keys are in use they should use at least a 2048-bit encryption algorithm.

use [<database_name>]

GO

SELECT name AS Key_Name, key_length

FROM sys.asymmetric_keys;

GO

Extensible Key Management (EKM)

Check

TODO

Enable

sp_configure 'show advanced', 1  

GO  

RECONFIGURE  

GO  

sp_configure 'EKM provider enabled', 1  

GO  

RECONFIGURE  

GO  

Usage

Bibliography

https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-database-encryption-key-transact-sql?redirectedfrom=MSDN&view=sql-server-ver15https://docs.microsoft.com/en-us/sql/t-sql/statements/create-master-key-transact-sql?view=sql-server-ver15https://docs.microsoft.com/en-gb/archive/blogs/batuhanyildiz/how-to-enableremove-transparent-data-encryption-tdehttps://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-database-encryption-keys-transact-sql?view=sql-server-ver15
https://learn.microsoft.com/en-us/sql/relational-databases/security/encryption/transparent-data-encryption
https://support.microsoft.com/en-gb/help/2300689/fix-you-cannot-restore-a-backup-of-a-database-on-another-instance-of-shttps://social.msdn.microsoft.com/Forums/sqlserver/en-US/f3bbe482-990f-44ce-b1ff-513c54e9a44a/certificates-and-key-rotation?forum=sqlsecurityhttps://social.msdn.microsoft.com/Forums/sqlserver/en-US/5b9e80e5-dd07-415e-ab2d-c177d7fd799d/alter-expirydate-of-a-certificate?forum=sqlsecurity
https://ss64.com/sql/certificate_c.html
https://www.mssqltips.com/sqlservertip/1312/managing-sql-server-master-keys-for-encryption/https://www.mssqltips.com/sqlservertip/1319/sql-server-encryption-certificates-overview/https://www.mssqltips.com/sqlservertip/5002/does-sql-server-tde-still-work-with-an-expired-certificate/
https://info.townsendsecurity.com/sql-server-always-encrypted-vs-transparent-data-encryption-tdehttps://edleightondick.com/2017/05/replacing-expiring-sql-encryption-key/https://matthewmcgiffen.com/2018/03/28/rotating-tde-certificates-without-re-encrypting-data/https://mattsql.wordpress.com/2012/11/13/migrating-sql-server-databases-that-use-database-master-keys/https://dataginger.com/2013/10/03/sql-server-encrypting-and-securing-native-backups-using-transparent-data-encryption-tde/https://www.brentozar.com/archive/2020/07/a-one-slide-summary-of-the-differences-between-tde-and-always-encrypted/https://stackoverflow.com/questions/14612993/encryption-status-in-sys-dm-database-encryption-keys-not-consistent-with-sys-dathttps://www.red-gate.com/simple-talk/sql/database-administration/transparent-data-encryption/https://www.databasejournal.com/tips/what-is-the-state-of-my-transparent-data-encrypted-database.html
Always Encryptedhttps://www.brentozar.com/archive/2020/07/a-one-slide-summary-of-the-differences-between-tde-and-always-encrypted/https://docs.microsoft.com/en-us/sql/relational-databases/security/encryption/always-encrypted-database-engine?view=sql-server-ver15https://www.mssqltips.com/sqlservertip/4011/sql-server-2016-always-encrypted/
EKMhttps://learn.microsoft.com/en-us/sql/relational-databases/security/encryption/extensible-key-management-ekm
Thales - CipherTrust Database Protection (CDP)https://thalesdocs.com/ctp/con/cdp/cdp-mssql/latest/admin/index.html