MSSQL Encryption
Transparent Data Encryption (TDE)
From SQL 2019 TDE is available in Standard Edition and Enterprise Edition. For earlier versions this was an Enterprise Edition only feature.
The tempdb system database will be encrypted if any other database on the instance of SQL Server is encrypted by using 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
0 = No encryption key present
1 = Unencrypted
2 = Encryption in progress
3 = Encrypted
4 = Key Change in Progress
5 = Decryption in Progress
6 = The certificate or asymmetric key that is encrypting the database encryption key is being changed
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
Store backup of encrypted keys on target server (e.g. local backup folder, but only IF it is considered secure. If you run backups to tape this has the added side-effect of storing the encryption key with the backup.. great for restoring, not so great if the tape is stolen). Alternatively keep it in a secure central certificate store.
Delete backups of old certificate but always keep at least one backup copy of every certificate you use until the last database backup that may possibly use them has been purged. If you ever need to restore a database that used encryption, you’ll need the certificate that was in effect at the time the backup was created.
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
store backup of encrypted keys on target server (e.g. local backup folder, but only IF it is considered secure) or in a secure central certificate store.
Delete backups of old certificate but always keep at least one backup copy of every certificate you use until the last database backup that may possibly use them has been purged. If you ever need to restore a database that used encryption, you’ll need the certificate that was in effect at the time the backup was created.
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
Check existing certificates and encrypted databases:
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
Decrypt database and drop key
--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
Perform full backup and TEST restore on DIFFERENT server
If there is no encrypted databases on server then you can drop certificate.
USE master
go
DROP CERTIFICATE TDECert1
go
DROP MASTER KEY
Delete backups of old certificate but always keep at least one backup copy of every certificate you use until the last database backup that may possibly use them has been purged. If you ever need to restore a database that used encryption, you’ll need the certificate that was in effect at the time the backup was created.
Delete TDE passwords from your secure password store (if you have one).
Backup/Restore
Use standard restore procedure if encrypted database with TDE needs to be restored with different name to original server
Use encrypted database restore procedure if database encrypted with TDE needs to be copied to different server
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://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