Updating notebooks for SQL Server 2019

This commit is contained in:
Amit Banerjee
2019-10-30 13:58:33 -07:00
parent a7a06f9ef9
commit a7c2f033ac
6 changed files with 82274 additions and 81521 deletions
@@ -0,0 +1,3 @@
# Security Notebooks
1. **TDE_on_Standard.ipynb** - This notebook demonstrates the ability to enable TDE on SQL Server 2019 Standard Edition along with Encryption Scan SUSPEND and RESUME.
2. **TDE_on_Standard_EKM.ipynb** - This notebook demonstrates the ability to enable TDE on a SQL Server 2019 Standard Edition using EKM and Azure Key Vault.
@@ -0,0 +1,545 @@
{
"metadata": {
"kernelspec": {
"name": "SQL",
"display_name": "SQL",
"language": "sql"
},
"language_info": {
"name": "sql",
"version": ""
}
},
"nbformat_minor": 2,
"nbformat": 4,
"cells": [
{
"cell_type": "markdown",
"source": [
"# Transparent Database Encryption in SQL Server 2019 Standard Edition\r\n",
"SQL Server 2019 will support Transparent Database Encryption to allow customers to encrypt their data-at-rest to stay in compliance with various security regulations while using SQL Server 2019 Standard Edition. More details about this feature can be found [here](https://docs.microsoft.com/en-us/sql/relational-databases/security/encryption/transparent-data-encryption?view=sql-server-ver15). Transparent Data Encryption (TDE) encrypts SQL Server, Azure SQL Database, and Azure SQL Data Warehouse data files, known as encrypting data at rest. \r\n",
"\r\n",
"In this notebook, you will be able to do the following:\r\n",
"1. Create a database on SQL Server 2019 Standard Edition\r\n",
"2. Enable TDE (Transparent Database Encryption) on the new database\r\n",
"3. PAUSE and RESUME encryption scan on the database"
],
"metadata": {
"azdata_cell_guid": "e65d5868-309c-4711-b41d-bec9b82dd4ff"
}
},
{
"cell_type": "markdown",
"source": [
"The following code snippet creates a database and enables TDE for the database."
],
"metadata": {
"azdata_cell_guid": "f76bfc2b-c433-4c90-b101-cd922f9417dc"
}
},
{
"cell_type": "code",
"source": [
"USE master; \r\n",
"GO \r\n",
"CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<UseStrongPasswordHere>'; \r\n",
"go \r\n",
"CREATE CERTIFICATE MyServerCert WITH SUBJECT = 'My DEK Certificate'; \r\n",
"go \r\n",
"CREATE DATABASE dbTDE\r\n",
"GO\r\n",
"USE dbTDE; \r\n",
"GO \r\n",
"CREATE TABLE tblTest (SNO int, val varchar(255));\r\n",
"INSERT INTO tblTest VALUES (1, 'TDE Test');\r\n",
"GO\r\n",
"SELECT name,is_encrypted from sys.databases WHERE name = 'dbTDE';\r\n",
"GO\r\n",
"CREATE DATABASE ENCRYPTION KEY \r\n",
"WITH ALGORITHM = AES_128 \r\n",
"ENCRYPTION BY SERVER CERTIFICATE MyServerCert; \r\n",
"GO "
],
"metadata": {
"azdata_cell_guid": "5cfa7085-36b1-4ba0-931f-5c483bf8934f"
},
"outputs": [],
"execution_count": 0
},
{
"cell_type": "markdown",
"source": [
"Verify that TDE is enabled on the database.\r\n",
"\r\n",
"# TDE is NOW available on STANDARD edition"
],
"metadata": {
"azdata_cell_guid": "2206f6f3-ce98-497c-a54e-5096dbd5a050"
}
},
{
"cell_type": "code",
"source": [
"SELECT SERVERPROPERTY('Edition') as Edition\r\n",
" ,name as [Database Name]\r\n",
" , CASE is_encrypted WHEN 1 THEN 'YES' ELSE 'NO' END as [Is TDE Enabled]\r\n",
"FROM sys.databases;"
],
"metadata": {
"azdata_cell_guid": "5782646a-4d2b-465c-92f0-1f1e29010575"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/html": "(5 rows affected)"
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "Total execution time: 00:00:00.025"
},
"metadata": {}
},
{
"output_type": "execute_result",
"metadata": {},
"execution_count": 9,
"data": {
"application/vnd.dataresource+json": {
"schema": {
"fields": [
{
"name": "Edition"
},
{
"name": "Database Name"
},
{
"name": "Is TDE Enabled"
}
]
},
"data": [
{
"0": "Standard Edition (64-bit)",
"1": "master",
"2": "NO"
},
{
"0": "Standard Edition (64-bit)",
"1": "tempdb",
"2": "YES"
},
{
"0": "Standard Edition (64-bit)",
"1": "model",
"2": "NO"
},
{
"0": "Standard Edition (64-bit)",
"1": "msdb",
"2": "NO"
},
{
"0": "Standard Edition (64-bit)",
"1": "dbTDE",
"2": "YES"
}
]
},
"text/html": "<table><tr><th>Edition</th><th>Database Name</th><th>Is TDE Enabled</th></tr><tr><td>Standard Edition (64-bit)</td><td>master</td><td>NO</td></tr><tr><td>Standard Edition (64-bit)</td><td>tempdb</td><td>YES</td></tr><tr><td>Standard Edition (64-bit)</td><td>model</td><td>NO</td></tr><tr><td>Standard Edition (64-bit)</td><td>msdb</td><td>NO</td></tr><tr><td>Standard Edition (64-bit)</td><td>dbTDE</td><td>YES</td></tr></table>"
}
}
],
"execution_count": 9
},
{
"cell_type": "markdown",
"source": [
"Now let's disable encryption on the database. As you can see from the output, TDE is disabled on the database."
],
"metadata": {
"azdata_cell_guid": "02d7afb6-53fb-4191-92d4-011d60288878"
}
},
{
"cell_type": "code",
"source": [
"ALTER DATABASE dbTDE set ENCRYPTION OFF;\r\n",
"WAITFOR DELAY '00:00:15'\r\n",
"SELECT SERVERPROPERTY('Edition') as Edition\r\n",
" ,name as [Database Name]\r\n",
" , CASE is_encrypted WHEN 1 THEN 'YES' ELSE 'NO' END as [Is TDE Enabled]\r\n",
"FROM sys.databases;"
],
"metadata": {
"azdata_cell_guid": "61480886-dc55-407e-96bf-d711b9ca9218"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/html": "(5 rows affected)"
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "Total execution time: 00:00:15.073"
},
"metadata": {}
},
{
"output_type": "execute_result",
"metadata": {},
"execution_count": 10,
"data": {
"application/vnd.dataresource+json": {
"schema": {
"fields": [
{
"name": "Edition"
},
{
"name": "Database Name"
},
{
"name": "Is TDE Enabled"
}
]
},
"data": [
{
"0": "Standard Edition (64-bit)",
"1": "master",
"2": "NO"
},
{
"0": "Standard Edition (64-bit)",
"1": "tempdb",
"2": "YES"
},
{
"0": "Standard Edition (64-bit)",
"1": "model",
"2": "NO"
},
{
"0": "Standard Edition (64-bit)",
"1": "msdb",
"2": "NO"
},
{
"0": "Standard Edition (64-bit)",
"1": "dbTDE",
"2": "NO"
}
]
},
"text/html": "<table><tr><th>Edition</th><th>Database Name</th><th>Is TDE Enabled</th></tr><tr><td>Standard Edition (64-bit)</td><td>master</td><td>NO</td></tr><tr><td>Standard Edition (64-bit)</td><td>tempdb</td><td>YES</td></tr><tr><td>Standard Edition (64-bit)</td><td>model</td><td>NO</td></tr><tr><td>Standard Edition (64-bit)</td><td>msdb</td><td>NO</td></tr><tr><td>Standard Edition (64-bit)</td><td>dbTDE</td><td>NO</td></tr></table>"
}
}
],
"execution_count": 10
},
{
"cell_type": "markdown",
"source": [
"Now let's reenable TDE on the database and pause the encryption scan as soon as it starts."
],
"metadata": {
"azdata_cell_guid": "74a81fd3-792d-4544-8b05-2633fc979a7e"
}
},
{
"cell_type": "code",
"source": [
"ALTER DATABASE dbTDE set ENCRYPTION ON;\r\n",
"ALTER DATABASE dbTDE SET ENCRYPTION SUSPEND;"
],
"metadata": {
"azdata_cell_guid": "b92f91a5-7d54-44da-b972-3210e25aa24e"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/html": "Commands completed successfully."
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "Total execution time: 00:00:00.051"
},
"metadata": {}
}
],
"execution_count": 11
},
{
"cell_type": "markdown",
"source": [
"The status of the encryption scan should say <b>SUSPENDED</b>"
],
"metadata": {
"azdata_cell_guid": "246599a5-4a2a-4455-8fdf-5c07f8c7317a"
}
},
{
"cell_type": "code",
"source": [
"SELECT db_name(database_id) as [Database Name]\r\n",
"\t, encryption_scan_modify_date\r\n",
"\t, encryption_scan_state_desc\r\n",
"from sys.dm_database_encryption_keys\r\n",
""
],
"metadata": {
"azdata_cell_guid": "6d9d9703-a744-4b93-8f2c-e0a429a71dbf"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/html": "(2 rows affected)"
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "Total execution time: 00:00:00.005"
},
"metadata": {}
},
{
"output_type": "execute_result",
"metadata": {},
"execution_count": 14,
"data": {
"application/vnd.dataresource+json": {
"schema": {
"fields": [
{
"name": "Database Name"
},
{
"name": "encryption_scan_modify_date"
},
{
"name": "encryption_scan_state_desc"
}
]
},
"data": [
{
"0": "tempdb",
"1": "2019-10-11 04:14:58.997",
"2": "COMPLETE"
},
{
"0": "dbTDE",
"1": "2019-10-29 22:48:20.150",
"2": "SUSPENDED"
}
]
},
"text/html": "<table><tr><th>Database Name</th><th>encryption_scan_modify_date</th><th>encryption_scan_state_desc</th></tr><tr><td>tempdb</td><td>2019-10-11 04:14:58.997</td><td>COMPLETE</td></tr><tr><td>dbTDE</td><td>2019-10-29 22:48:20.150</td><td>SUSPENDED</td></tr></table>"
}
}
],
"execution_count": 14
},
{
"cell_type": "markdown",
"source": [
"Let's resume the encryption "
],
"metadata": {
"azdata_cell_guid": "7ed73073-d0f3-4bf6-9836-8534422fc765"
}
},
{
"cell_type": "code",
"source": [
"ALTER DATABASE dbTDE SET ENCRYPTION RESUME;"
],
"metadata": {
"azdata_cell_guid": "57af9c9f-9e4c-4f65-ada4-123f46d2b8ae"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/html": "Commands completed successfully."
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "Total execution time: 00:00:00.012"
},
"metadata": {}
}
],
"execution_count": 15
},
{
"cell_type": "markdown",
"source": [
"Check if the encryption is complete"
],
"metadata": {
"azdata_cell_guid": "563c6218-13c8-4a67-ab29-7a7c5251b501"
}
},
{
"cell_type": "code",
"source": [
"SELECT db_name(database_id) as [Database Name]\r\n",
"\t, encryption_scan_modify_date\r\n",
"\t, encryption_scan_state_desc\r\n",
"FROM sys.dm_database_encryption_keys;\r\n",
"\r\n",
"SELECT SERVERPROPERTY('Edition') as Edition\r\n",
" ,name as [Database Name]\r\n",
" , CASE is_encrypted WHEN 1 THEN 'YES' ELSE 'NO' END as [Is TDE Enabled]\r\n",
"FROM sys.databases;"
],
"metadata": {
"azdata_cell_guid": "5b87157b-a1f2-4802-868a-9b76beaa6453"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/html": "(2 rows affected)"
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "(5 rows affected)"
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "Total execution time: 00:00:00.036"
},
"metadata": {}
},
{
"output_type": "execute_result",
"metadata": {},
"execution_count": 16,
"data": {
"application/vnd.dataresource+json": {
"schema": {
"fields": [
{
"name": "Database Name"
},
{
"name": "encryption_scan_modify_date"
},
{
"name": "encryption_scan_state_desc"
}
]
},
"data": [
{
"0": "tempdb",
"1": "2019-10-11 04:14:58.997",
"2": "COMPLETE"
},
{
"0": "dbTDE",
"1": "2019-10-29 22:58:34.353",
"2": "COMPLETE"
}
]
},
"text/html": "<table><tr><th>Database Name</th><th>encryption_scan_modify_date</th><th>encryption_scan_state_desc</th></tr><tr><td>tempdb</td><td>2019-10-11 04:14:58.997</td><td>COMPLETE</td></tr><tr><td>dbTDE</td><td>2019-10-29 22:58:34.353</td><td>COMPLETE</td></tr></table>"
}
},
{
"output_type": "execute_result",
"metadata": {},
"execution_count": 16,
"data": {
"application/vnd.dataresource+json": {
"schema": {
"fields": [
{
"name": "Edition"
},
{
"name": "Database Name"
},
{
"name": "Is TDE Enabled"
}
]
},
"data": [
{
"0": "Standard Edition (64-bit)",
"1": "master",
"2": "NO"
},
{
"0": "Standard Edition (64-bit)",
"1": "tempdb",
"2": "YES"
},
{
"0": "Standard Edition (64-bit)",
"1": "model",
"2": "NO"
},
{
"0": "Standard Edition (64-bit)",
"1": "msdb",
"2": "NO"
},
{
"0": "Standard Edition (64-bit)",
"1": "dbTDE",
"2": "YES"
}
]
},
"text/html": "<table><tr><th>Edition</th><th>Database Name</th><th>Is TDE Enabled</th></tr><tr><td>Standard Edition (64-bit)</td><td>master</td><td>NO</td></tr><tr><td>Standard Edition (64-bit)</td><td>tempdb</td><td>YES</td></tr><tr><td>Standard Edition (64-bit)</td><td>model</td><td>NO</td></tr><tr><td>Standard Edition (64-bit)</td><td>msdb</td><td>NO</td></tr><tr><td>Standard Edition (64-bit)</td><td>dbTDE</td><td>YES</td></tr></table>"
}
}
],
"execution_count": 16
},
{
"cell_type": "markdown",
"source": [
"You should see the following messages in the SQL Server errorlog which shows PAUSE and RESUME for the encryption scan.\r\n",
"\r\n",
"\r\n",
"<i> 2019-10-29 22:32:11.100 spid34s Beginning database encryption scan for database 'dbTDE'. <br>\r\n",
"2019-10-29 22:32:11.150 spid34s <font color = \"red\">Database encryption scan for database 'dbTDE' was aborted.</font> Reissue ALTER DB to resume the scan. <br>\r\n",
"2019-10-29 22:32:31.730 spid15s <font color =\"red\">Beginning database encryption scan for database 'dbTDE'.</font> <br>\r\n",
"2019-10-29 22:32:41.190 spid15s Database encryption scan for database 'dbTDE' is complete. </i> <br>"
],
"metadata": {
"azdata_cell_guid": "986ce50e-faa9-4f35-8156-8f1cd6fbcb2d"
}
}
]
}
@@ -0,0 +1,462 @@
{
"metadata": {
"kernelspec": {
"name": "SQL",
"display_name": "SQL",
"language": "sql"
},
"language_info": {
"name": "sql",
"version": ""
}
},
"nbformat_minor": 2,
"nbformat": 4,
"cells": [
{
"cell_type": "markdown",
"source": [
"# SQL Server 2019 Standard Edition, Transparent Database Encryption and Azure Key Vault\r\n",
"\r\n",
"This notebook demonstrates the use of Azure Key Vault to enable TDE on a SQL Server 2019 Standard Edition database using EKM.\r\n",
"\r\n",
"**Pre-requisities** \r\n",
"1. Install Python\r\n",
"2. Install Azure CLI using the following command (You will need to ensure that the Python scripts folder is part of your PATH variable)\r\n",
" <br> <code>pip install --user azure-cli</code>\r\n",
"3. Log into Azure and create and Azure AD Service Principal\r\n",
" <code><br> az login\r\n",
" <br> az account set --subscription <-subscription id->\r\n",
" <br> az ad sp create-for-rbac -n sqlaadtde --skip-assignment\r\n",
" </code>\r\n",
" <br> note the <b>appID</b> value which would be required later\r\n",
" <code>\r\n",
" <br>{\"appId\": \"<-guid->\",\r\n",
" <br>\"displayName\": \"sqlaadtde\",\r\n",
" <br>\"name\": \"http://sqlaadtde\",\r\n",
" <br>\"password\": \"<-guid->\",\r\n",
" <br>\"tenant\": \"<-guid->\"}\r\n",
" </code>\r\n",
"4. Create a new resource group and assign a newly created Azure Key Vault to the same resource group\r\n",
" <code>\r\n",
" <br> # Create a new resource group\r\n",
" <br> az group create -n \"SQLTDEResourceGroup\" -l \"West US\"\r\n",
" <br> # Register the Key Vault resource provider\r\n",
" <br> az provider register -n Microsoft.KeyVault\r\n",
" <br> az keyvault create --name \"SQLStandardKeyVault\" --resource-group \"SQLTDEResourceGroup\" --location \"West US\"\r\n",
" </code>\r\n",
"5. Register the Azure AD principl with AKV\r\n",
" <code>\r\n",
" <br> # Register the AAD principal\r\n",
" <br> az keyvault set-policy --name \"SQLStandardKeyVault\" --spn <appID GUID from az ad create-for-rbac output> --key-permissions get list wrapKey unwrapKey --verbose\r\n",
" </code>\r\n",
"\r\n",
"Details about the scenario is available [here](https://docs.microsoft.com/en-us/sql/relational-databases/security/encryption/setup-steps-for-extensible-key-management-using-the-azure-key-vault?view=sql-server-ver15#next-step)."
],
"metadata": {
"azdata_cell_guid": "f28683d2-1f27-42b3-8418-f6747ed878ec"
}
},
{
"cell_type": "markdown",
"source": [
"### Configure SQL Server to use EKM\r\n",
"Download and install the [SQL Server Connector](https://go.microsoft.com/fwlink/p/?LinkId=521700). (This should be done by the administrator of the SQL Server computer.) By default, the connector installs at <b>C:\\Program Files\\SQL Server Connector for Microsoft Azure Key Vault</b>. This location can be changed during setup. (If changed, adjust the scripts below.)\r\n",
"<br>There is no interface for the Connector, but if it is installed successfully, the <b>Microsoft.AzureKeyVaultService.EKM.dll</b> is installed on the machine. This is the cryptographic EKM provider DLL that needs to be registered with SQL Server by using the CREATE CRYPTOGRAPHIC PROVIDER statement."
],
"metadata": {
"azdata_cell_guid": "c82cb49a-7e5c-419e-b109-da7d2f9defa0"
}
},
{
"cell_type": "code",
"source": [
"USE master; \r\n",
"GO \r\n",
"\r\n",
"sp_configure 'show advanced options', 1; \r\n",
"GO \r\n",
"RECONFIGURE WITH OVERRIDE; \r\n",
"GO \r\n",
"\r\n",
"-- Enable EKM provider \r\n",
"sp_configure 'EKM provider enabled', 1; \r\n",
"GO \r\n",
"RECONFIGURE WITH OVERRIDE; \r\n",
"GO"
],
"metadata": {
"azdata_cell_guid": "4e7af918-31d1-40c2-a193-309672e1c0ef"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/html": "Commands completed successfully."
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "Configuration option 'show advanced options' changed from 1 to 1. Run the RECONFIGURE statement to install."
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "Commands completed successfully."
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "Configuration option 'EKM provider enabled' changed from 1 to 1. Run the RECONFIGURE statement to install."
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "Commands completed successfully."
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "Total execution time: 00:00:00.059"
},
"metadata": {}
}
],
"execution_count": 15
},
{
"cell_type": "markdown",
"source": [
"### Register (create) the SQL Server Connector as an EKM provider with SQL Server"
],
"metadata": {
"azdata_cell_guid": "27394b2a-b1da-497b-8c56-8a2fbd1af037"
}
},
{
"cell_type": "code",
"source": [
"-- Create a cryptographic provider, using the SQL Server Connector\r\n",
"-- which is an EKM provider for the Azure Key Vault. This example uses \r\n",
"-- the name AzureKeyVault_EKM_Prov.\r\n",
"\r\n",
"CREATE CRYPTOGRAPHIC PROVIDER AzureKeyVault_EKM_Prov \r\n",
"FROM FILE = 'C:\\Program Files\\SQL Server Connector for Microsoft Azure Key Vault\\Microsoft.AzureKeyVaultService.EKM.dll';\r\n",
"GO \r\n",
""
],
"metadata": {
"azdata_cell_guid": "3f53701d-b27a-49a8-931e-e3319c1b6386"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/html": "Commands completed successfully."
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "Total execution time: 00:00:00.022"
},
"metadata": {}
}
],
"execution_count": 16
},
{
"cell_type": "markdown",
"source": [
"### Create a credential from your AAD Client ID and Secret that you can use to grant a SQL Server account access to your Azure key vault\r\n",
"The IDENTITY here is the name of your Azure key vault.\r\n",
"<br>The SECRET here is your AAD Client ID (with the hyphens removed) and your AAD Client Secret concatenanted together\r\n",
"<br>You will need to create a \"New Client Secret\" for your Azure AD app registration i.e. *sqlaadtde*, which was created above. See steps [here](https://docs.microsoft.com/en-us/azure/healthcare-apis/register-confidential-azure-ad-client-app#application-secret)."
],
"metadata": {
"azdata_cell_guid": "e71869f8-0904-4167-8818-c7cb345915c0"
}
},
{
"cell_type": "code",
"source": [
"CREATE CREDENTIAL Azure_EKM_TDE_cred\r\n",
" WITH IDENTITY = 'SQLStandardKeyVault', -- for global Azure\r\n",
" -- WITH IDENTITY = 'ContosoDevKeyVault.vault.usgovcloudapi.net', -- for Azure Government\r\n",
" -- WITH IDENTITY = 'ContosoDevKeyVault.vault.azure.cn', -- for Azure China 21Vianet\r\n",
" -- WITH IDENTITY = 'ContosoDevKeyVault.vault.microsoftazure.de', -- for Azure Germany \r\n",
"\tSECRET = '<combination of AAD Client ID without hyphens and AAD Client Secret>'\r\n",
" FOR CRYPTOGRAPHIC PROVIDER AzureKeyVault_EKM_Prov \r\n",
"\r\n",
""
],
"metadata": {
"azdata_cell_guid": "600cf82f-0488-46da-a253-99146f20065b"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/html": "Commands completed successfully."
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "Total execution time: 00:00:00.012"
},
"metadata": {}
}
],
"execution_count": 25
},
{
"cell_type": "markdown",
"source": [
"### Create an Asymmetric Key using the AKV Key\r\n",
"You will need to first create a Key in Azure Key Vault which can be used to create the Asymmetric Key in SQL Server\r\n",
"<code>\r\n",
"<br> # Create a software-protected key \r\n",
"<br> az keyvault key create --vault-name \"SQLStandardKeyVault\" --name \"SQLTDEKey\" --protection software\r\n",
"</code>"
],
"metadata": {
"azdata_cell_guid": "ef0ab374-182e-434b-b7d8-050b3a1c481b"
}
},
{
"cell_type": "code",
"source": [
"CREATE ASYMMETRIC KEY dbAKV_Key \r\n",
"FROM PROVIDER [AzureKeyVault_EKM_Prov] \r\n",
"WITH PROVIDER_KEY_NAME = 'SQLTDEKey', -- This is the KEY that was created in the Azure Key Vault\r\n",
"CREATION_DISPOSITION = OPEN_EXISTING;"
],
"metadata": {
"azdata_cell_guid": "923e5bc8-2751-4286-a0fe-fa37e1af59b0"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/html": "Commands completed successfully."
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "Total execution time: 00:00:00.145"
},
"metadata": {}
}
],
"execution_count": 27
},
{
"cell_type": "markdown",
"source": [
"### Now create a database and enable TDE on the database"
],
"metadata": {
"azdata_cell_guid": "c87fa2c2-1d3f-4dda-a2f9-d320af41486a"
}
},
{
"cell_type": "code",
"source": [
"USE master; \r\n",
"-- Create a SQL Server login associated with the asymmetric key \r\n",
"-- for the Database engine to use when it loads a database \r\n",
"-- encrypted by TDE. \r\n",
"CREATE LOGIN TDE_Login \r\n",
"FROM ASYMMETRIC KEY dbAKV_Key; \r\n",
"GO \r\n",
"\r\n",
"-- Alter the TDE Login to add the credential for use by the \r\n",
"-- Database Engine to access the key vault \r\n",
"ALTER LOGIN TDE_Login \r\n",
"ADD CREDENTIAL Azure_EKM_TDE_cred ; \r\n",
"GO\r\n",
"\r\n",
"CREATE DATABASE dbAKVTDE;\r\n",
"GO \r\n",
"USE dbAKVTDE;\r\n",
"GO\r\n",
"\r\n",
"CREATE DATABASE ENCRYPTION KEY \r\n",
"WITH ALGORITHM = AES_256 \r\n",
"ENCRYPTION BY SERVER ASYMMETRIC KEY dbAKV_Key; -- Use the key created above\r\n",
"GO \r\n",
"\r\n",
"-- Alter the database to enable transparent data encryption. \r\n",
"ALTER DATABASE dbAKVTDE \r\n",
"SET ENCRYPTION ON; \r\n",
"GO "
],
"metadata": {
"azdata_cell_guid": "ee35f210-c356-4018-8994-057d16273b3a"
},
"outputs": [],
"execution_count": 30
},
{
"cell_type": "markdown",
"source": [
"## Check if the database has been encrypted"
],
"metadata": {
"azdata_cell_guid": "6b8f4ad6-4998-4c0f-8fe5-f1a23d95055f"
}
},
{
"cell_type": "code",
"source": [
"USE MASTER \r\n",
"SELECT name,provider_type, algorithm_desc FROM sys.asymmetric_keys \r\n",
"\r\n",
"-- Check which databases are encrypted using TDE \r\n",
"SELECT SERVERPROPERTY('Edition') as [Edition],d.name, dek.encryption_scan_state_desc, dek.encryptor_type \r\n",
"FROM sys.dm_database_encryption_keys AS dek \r\n",
"JOIN sys.databases AS d \r\n",
" ON dek.database_id = d.database_id;"
],
"metadata": {
"azdata_cell_guid": "557fb1b5-7058-4888-986e-1ef2c03a1ab9"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/html": "(1 row affected)"
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "(3 rows affected)"
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/html": "Total execution time: 00:00:00.048"
},
"metadata": {}
},
{
"output_type": "execute_result",
"metadata": {},
"execution_count": 36,
"data": {
"application/vnd.dataresource+json": {
"schema": {
"fields": [
{
"name": "name"
},
{
"name": "provider_type"
},
{
"name": "algorithm_desc"
}
]
},
"data": [
{
"0": "dbAKV_Key",
"1": "CRYPTOGRAPHIC PROVIDER",
"2": "RSA_2048"
}
]
},
"text/html": "<table><tr><th>name</th><th>provider_type</th><th>algorithm_desc</th></tr><tr><td>dbAKV_Key</td><td>CRYPTOGRAPHIC PROVIDER</td><td>RSA_2048</td></tr></table>"
}
},
{
"output_type": "execute_result",
"metadata": {},
"execution_count": 36,
"data": {
"application/vnd.dataresource+json": {
"schema": {
"fields": [
{
"name": "Edition"
},
{
"name": "name"
},
{
"name": "encryption_scan_state_desc"
},
{
"name": "encryptor_type"
}
]
},
"data": [
{
"0": "Standard Edition (64-bit)",
"1": "tempdb",
"2": "COMPLETE",
"3": "ASYMMETRIC KEY"
},
{
"0": "Standard Edition (64-bit)",
"1": "dbTDE",
"2": "COMPLETE",
"3": "CERTIFICATE"
},
{
"0": "Standard Edition (64-bit)",
"1": "dbAKVTDE",
"2": "COMPLETE",
"3": "ASYMMETRIC KEY"
}
]
},
"text/html": "<table><tr><th>Edition</th><th>name</th><th>encryption_scan_state_desc</th><th>encryptor_type</th></tr><tr><td>Standard Edition (64-bit)</td><td>tempdb</td><td>COMPLETE</td><td>ASYMMETRIC KEY</td></tr><tr><td>Standard Edition (64-bit)</td><td>dbTDE</td><td>COMPLETE</td><td>CERTIFICATE</td></tr><tr><td>Standard Edition (64-bit)</td><td>dbAKVTDE</td><td>COMPLETE</td><td>ASYMMETRIC KEY</td></tr></table>"
}
}
],
"execution_count": 36
},
{
"cell_type": "markdown",
"source": [
"# Best Practices\r\n",
"To ensure quick key recovery and be able to access your data outside of Azure, we recommend the following best practices:\r\n",
"<br> a. Create your encryption key locally on a local HSM device. (Make sure this is an asymmetric, RSA 2048 key so it's is supported by SQL Server.)\r\n",
"<br> b. Import the encryption key to Azure Key Vault. See the steps in this [article](https://docs.microsoft.com/en-us/sql/relational-databases/security/encryption/setup-steps-for-extensible-key-management-using-the-azure-key-vault?view=sql-server-ver15#part-ii-create-a-key-vault-and-key) on how to do that.\r\n",
"<br> c. Before using the key in Azure Key Vault for the first time, take an Azure Key Vault key backup. Learn more about the <b>Backup-AzureKeyVaultKey</b> command.\r\n",
"Whenever any changes are made to the key (for example add ACLs, add tags, add key attributes), be sure to take another Azure Key Vault key backup.\r\n",
"\r\n",
"## Types of keys\r\n",
"There are two types of keys you can generate in Azure Key Vault that will work with SQL Server. Both are asymmetric 2048-bit RSA keys.\r\n",
"<br><b>Software-protected</b>: Processed in software and encrypted at rest. Operations on software-protected keys occur on Azure Virtual Machines. Recommended for keys not used in a production deployment.\r\n",
"<br><b>HSM-protected</b>: Created and protected by a hardware security module (HSM) for additional security.\r\n",
"\r\n",
"For common troubleshooting and maintenance of the SQL Server Connector, please refer to [this article](https://docs.microsoft.com/en-us/sql/relational-databases/security/encryption/sql-server-connector-maintenance-troubleshooting?view=sql-server-ver15)."
],
"metadata": {
"azdata_cell_guid": "b74a3595-b2e9-4952-8e2a-c5876f740b70"
}
}
]
}