Database Encryption
Database Encryption
Enable Transparent Data Encryption (TDE) using DuoKey EKM
Overview
Transparent Data Encryption (TDE) encrypts the storage of an entire database using a Database Encryption Key (DEK). With DuoKey EKM, this DEK is protected by an asymmetric key stored in DuoKey's cloud platform, providing an additional layer of security.
Prerequisites
- SQL Server configured with DuoKey EKM Provider
- Asymmetric key created and encryption enabled in DuoKey
- SQL Server Management Studio (SSMS) installed
- Sysadmin privileges on SQL Server
Encryption Hierarchy
DuoKey Cloud Platform
Master Encryption Key (MEK)
MPC ProtectedSQL Server (master database)
Asymmetric Key (EKM)
RSA-2048User Database
Database Encryption Key (DEK)
AES-256Data Files
.mdf, .ndf, .ldf
Encrypted at RestCreate Database and Enable TDE
Create or Select Database
Create a new database or use an existing one:
-- Create a new database
CREATE DATABASE EmployeeDB;
GO
USE EmployeeDB;
CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
FirstName VARCHAR(128),
LastName VARCHAR(128),
Salary DECIMAL(10, 2),
SSN VARCHAR(11)
);
GOCreate Database Encryption Key
Create a DEK protected by the asymmetric key in DuoKey:
USE EmployeeDB;
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_256
ENCRYPTION BY SERVER ASYMMETRIC KEY SQL_EKM_Key;
GO| Algorithm | Key Size | Recommendation |
|---|---|---|
| AES_128 | 128-bit | Good security |
| AES_192 | 192-bit | Better security |
| AES_256 | 256-bit | Recommended - strongest |
Always choose an AES algorithm for the DEK. AES_256 is recommended.
Use AES_256 for the strongest encryption. It provides excellent security with minimal performance impact on modern hardware.
Enable Encryption
Enable TDE on the database:
ALTER DATABASE EmployeeDB
SET ENCRYPTION ON;
GOEncryption is performed asynchronously. For large databases, this process may take some time.
Encrypted databases reopen automatically after a SQL Server restart. The EKM provider keystore lets the DEK be unwrapped by the DuoKey-held master key without manual intervention.
Monitor Encryption Progress
SELECT
DB_NAME(database_id) AS DatabaseName,
encryption_state,
CASE encryption_state
WHEN 0 THEN 'No database encryption key present'
WHEN 1 THEN 'Unencrypted'
WHEN 2 THEN 'Encryption in progress'
WHEN 3 THEN 'Encrypted'
WHEN 4 THEN 'Key change in progress'
WHEN 5 THEN 'Decryption in progress'
WHEN 6 THEN 'Protection change in progress'
END AS Status,
percent_complete,
encryptor_type
FROM sys.dm_database_encryption_keys;
GOEncryption States Reference
| State | Value | Description | Action Required |
|---|---|---|---|
| 0 | No DEK | No database encryption key present | Create DEK with CREATE DATABASE ENCRYPTION KEY |
| 1 | Unencrypted | DEK exists but encryption not enabled | Enable with ALTER DATABASE SET ENCRYPTION ON |
| 2 | Encrypting | Encryption in progress | Wait for completion, monitor percent_complete |
| 3 | Encrypted | Database fully encrypted | None - normal operation |
| 4 | Key Change | Key rotation in progress | Wait for completion |
| 5 | Decrypting | Decryption in progress | Wait for completion |
| 6 | Protection Change | Protector change in progress | Wait for completion |
Verify Encryption
SELECT
d.name AS DatabaseName,
d.is_encrypted,
dek.encryption_state,
dek.percent_complete,
dek.key_algorithm,
dek.key_length
FROM sys.databases d
LEFT JOIN sys.dm_database_encryption_keys dek
ON d.database_id = dek.database_id
WHERE d.name = 'EmployeeDB';
GOUSE master;
SELECT
ak.name AS AsymmetricKeyName,
ak.algorithm_desc,
ak.key_length,
cp.name AS CryptoProviderName
FROM sys.asymmetric_keys ak
INNER JOIN sys.cryptographic_providers cp
ON ak.cryptographic_provider_guid = cp.guid;
GOTest Data Operations
After encryption is enabled, test that data operations work transparently:
USE EmployeeDB;
-- Insert test data
INSERT INTO Employees (EmployeeID, FirstName, LastName, Salary, SSN)
VALUES
(1, 'John', 'Doe', 75000.00, '123-45-6789'),
(2, 'Jane', 'Smith', 82000.00, '987-65-4321'),
(3, 'Bob', 'Johnson', 68000.00, '555-12-3456');
GO
-- Query data (works transparently)
SELECT * FROM Employees;
GOThe data is automatically encrypted at rest while remaining transparent to applications.
Performance Considerations
Initial Encryption
- CPU: Moderate increase
- I/O: Significant activity
- Speed: ~1-5 GB/minute
- Database remains online
Ongoing Impact
- Read operations: 3-5% overhead
- Write operations: 5-10% overhead
- CPU usage: 1-3% increase
- AES-NI reduces impact
- Schedule initial encryption during maintenance windows
- Monitor CPU and I/O during encryption
- Use AES-NI capable processors for best performance
- Ensure adequate tempdb space
Encrypt Multiple Databases
Use a script to encrypt multiple databases at once:
DECLARE @dbname NVARCHAR(128);
DECLARE @sql NVARCHAR(MAX);
DECLARE db_cursor CURSOR FOR
SELECT name FROM sys.databases
WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb')
AND is_encrypted = 0;
OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @dbname;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql = N'USE [' + @dbname + '];
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_256
ENCRYPTION BY SERVER ASYMMETRIC KEY SQL_EKM_Key;
ALTER DATABASE [' + @dbname + '] SET ENCRYPTION ON;';
EXEC sp_executesql @sql;
PRINT 'Encrypted database: ' + @dbname;
FETCH NEXT FROM db_cursor INTO @dbname;
END;
CLOSE db_cursor;
DEALLOCATE db_cursor;
GODisable Encryption
Disabling encryption will decrypt the database, which may take considerable time for large databases.
-- Disable encryption
ALTER DATABASE EmployeeDB
SET ENCRYPTION OFF;
GO
-- Monitor decryption progress
SELECT
DB_NAME(database_id) AS DatabaseName,
encryption_state,
percent_complete
FROM sys.dm_database_encryption_keys
WHERE DB_NAME(database_id) = 'EmployeeDB';
GO
-- After decryption completes (encryption_state = 1)
USE EmployeeDB;
DROP DATABASE ENCRYPTION KEY;
GOBest Practices
Security
Encrypt databases early, protect backup keys, audit key access
Operations
Test before production, monitor performance, plan for growth
Maintenance
Regular backups, test restores, keep DuoKey accessible