I recently implemented database encryption using Symmetric/Asymmetric keys and have the Database Master Key (DMK) encrypted by password. Now if I'm understand the encryption hierarchy correctly, the DMK password will then be stored in the master database and is encrypted by the Service Master Key (SMK). My goal is to copy the database to another server to serve as a "test environment". In order to do so, I'll need to restore a copy of the Service Master Key on the destination server in order to properly encrypt/decrypt the data. I just want make sure that I'm reading the documentation correctly regarding the RESTORE MASTER KEY command. When I restore the SMK, any encrypted data on the destination server will first be decrypted by the current SMK and then re-encrypted using the new SMK. Is it safe to assume that no other database should be adversely affected if they have encryption?
Looking at the syntax for CREATE DATABASE ENCRYPTION KEY, the database master key (DMK) is encrypted by either a server-level certificate or a server-level asymmetric key. In order to restore that database on another server, the certificate or asymmetric key that protects the DMK needs to be present in the master database at the destination. Once you have that, you should be good to go.
If this is a cross-environment restore (e.g. prod → dev), I like to re-encrypt the key with an encryptor that doesn't exist at the source. It's a little added protection that ensures that the restore happens one way (i.e. you can't overwrite prod with dev).
Related
I have an SQL instance with multiple data bases. Each of them are TDE encrypted.
I know that all data bases use the same service master key, SMK, to encrypt tempdb. I have back up the SMK using:
BACKUP SERVICE MASTER KEY
TO FILE = 'tmp-path.key'
ENCRYPTION BY PASSWORD = 'temp-password';
Now, how do I back up the distinct database master key, DMK? Each data base use a different one, but the SQL statement doesn't allow to specify which one to back up. Next, is the command I'm running.
BACKUP MASTER KEY
TO FILE = 'tmep-path.key'
ENCRYPTION BY PASSWORD = 'temp-passowrd'
I though that by:
use [specific-db];
GO
It will back up an specific one, but the command won't run. You need to be on master, to run the command.
Thanks
The way TDE is configured in SQL Server is as follow:
Create Master key in master database
Create Certificate using the master key
Create Database Encryption key using the certificate
There are only two things you need to/can backup here:
Master Encryption Key - The script you have shown in your question will do that.
BACKUP MASTER KEY
TO FILE = 'tmep-path.key'
ENCRYPTION BY PASSWORD = 'temp-passowrd'
Certificate - You can either create a separate Certificate for each database to be encrypted or a single certificate to encrypt all database, You will create and backup the certificate as follow:
-- Create Certificate
USE Master;
GO
CREATE CERTIFICATE TDE_MyDB_Cert
WITH SUBJECT = 'My TDE Certificate for MyDB user database'
GO
This certificate is protected by the service master key.
-- Encrypt Database using the Certificate
USE [MyDB]
GO
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_128
ENCRYPTION BY SERVER CERTIFICATE TDE_MyDB_Cert
GO
Now you need to backup the certificate with the private key for the database which you would do, doing:
USE master;
GO
BACKUP CERTIFICATE TDE_MyDB_Cert
TO FILE = 'C:\TDE_MyDB_Cert_File.cer'
WITH PRIVATE KEY (FILE = 'C:\TDE_MyDB_Cert_PKey.pvk' ,
ENCRYPTION BY PASSWORD = 'S0M34tR0nGP#$$w)rd' )
GO
TDE_MyDB_Cert_File.cer Is the certificate backup
TDE_MyDB_Cert_PKey.pvk is the backup for Private key for the database
We need to configure Always Encrypted feature for all databases. We wanted to create common Column Master Key in Master database so that we can link CMK to all databases on server. But we are not able to link CMK created in master DB to all databases. We need to create individually create master key in each database. Is there any way to create a CMK in master database and refer to all databases on the server.
Column Master Key is per-database object, i.e. you can't share it between databases. However, it is nothing more than metadata, i.e. a pointer where the actual key (certificate) is stored. With Always Encrypted the database do not have access to the actual encryption keys. They are stored in external key store (Windows Certificate Store, Azure Key Vault). So what you need to do is to replicate (copy) the existing certificate by registering it in the rest of the databases. Just script the existing CMK as CREATE COLUMN MASTER KEY statement and execute it in each of the databases:
CREATE COLUMN MASTER KEY [CMK_Auto1]
WITH
(
KEY_STORE_PROVIDER_NAME = N'MSSQL_CERTIFICATE_STORE',
KEY_PATH = N'CurrentUser/my/2CC027B4FCA85D4244B528E8CA5F73D1EBB18C69'
)
GO
This will create a new CMK in each database, but all of them will use the same certificate to encrypt the data. Then encrypt the columns you want using the existing CMK, which you created with the script above.
I know that, when a DB is restored then in-order to use the decrypted data its DMK needs to be reopened with following query.
OPEN MASTER KEY DECRYPTION BY PASSWORD = ''
ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY
CLOSE MASTER KEY
Now the issue is, the DB restore is performed by scripts and pretty much automated. Now after encryption I cannot include the above commands in the script as it will include the password in plain Text. Is there any way to hide this password, or to re-open the DMK without the password?
I have two instances of SQL Server 2016 Enterprise, each running on a different server. They are standalone servers. There is a shared drive on ServerA which can be accessed from ServerB.
I have set up log shipping from a database (TESTDB) on MAIN_DB to one on MAIN_UAT. I did this by creating the same local user profile on each server (SQLService) with the same password and changing the SQL Agent and SQL Server jobs to run under this profile on each server using SQL Server Configuration Manager. This seems to work quite happily.
I then tried to implement TDE on the databases.
In the first instance, I stopped log shipping. I then created a second database (TESTDB2) on MAIN_DB and set up log shipping to that from the primary database on MAIN_UAT. Then I used this script to set up TDE. Once the backup and restore cycle had run, TESTDB2 was also encrypted. Again, this worked without problems.
use master
go
create master key encryption by password='something cryptic'
go
create certificate TDECertificate with subject='Log Shipping certificate'
go
create database encryption key with algorithm=AES_256 encryption by server certificate TDECertificate
alter database TestDB set encryption on
I then tried to reproduce this on the secondary server – MAIN_UAT. On the primary server I ran this script.
backup certificate TDECertificate to file='D:\Certificates\myCertificate.crt'
with private key (file='D:\LANSHARE\Certificates\LogShippingKey.key',encryption by password='something cryptic')
backup master key to file='D:\Certificates\MasterKey.key' encryption by password='something cryptic'
I copied the three resulting files into a folder on the secondary server and gave SQLService (the local user) full control over the folder and files. I then tried to install the certificate on the secondary server with this script.
use master
go
restore master key from file='D:\Certificates\MasterKey.key' decryption by password='something cryptic'encryption by password='something cryptic'
go
create certificate TDECertificate from file='D:\Certificates\myCertificate.crt' with private key (file='D:\Certificates\LogShippingKey.key',decryption by password='something cryptic',encryption by password='something cryptic')
go
use TESTDB2
go
create database encryption key with algorithm=AES_256 encryption by server certificate TDECertificate
This gave me this error, which is where I’m stuck.
Msg 15151, Level 16, State 1, Line 14
Cannot find the certificate 'TDECertificate', because it does not exist or you do not have permission.
In a nutshell, how do I implement TDE with log shipping on servers on different domains?
Thanks for any help you can give.
Where is the SQL Server Database master key (DMK) password stored? Is it stored in master database? in registry?. If the hacker gets hold of the mdf files will he be able to get the password that was used to create DMK?
In the SQL Server there is Encryption Hierarchy - everything is encrypted by something. You can create one Database Mater Key in each database in order to protect the certificates, assymetric and symetric keys in it - the DMK is used to encrypted them.
Database master keys are protected by the Service Master Key. The
Service Master Key is created by SQL Server setup and is encrypted
with the Windows Data Protection API (DPAPI).
Let's say we have a database backup and restore it to our local instance. If I try to read some of the ecnrypted data, without knowing the DMK password in order to encrypt the certificate I am getting the following error:
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'I_DO_NOT_KNOW_THE_PASS';
SELECT *, CAST(DecryptByAsymKey(AsymKey_ID(N'smGK_АSymmetricKey_01'), BufferEncryptedEmail) AS NVARCHAR(444))
FROM SecurityUsersAssimetricKey
CLOSE MASTER KEY
Msg 15313, Level 16, State 1, Line 1 The key is not encrypted using
the specified decryptor.
So, in my case (when the DMK is encrtpyed by password), I can only read the ecnrypted data knowing the password:
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'smGK_MasterKeyPassword';
SELECT *, CAST(DecryptByAsymKey(AsymKey_ID(N'smGK_АSymmetricKey_01'), BufferEncryptedEmail) AS NVARCHAR(444))
FROM SecurityUsersAssimetricKey
CLOSE MASTER KEY
In order to protect the whole data, you can check howbackup encryption is made.
If backup encryption is applied, the backup is encrypted using certificate. Without this certificated, the backup cannot be restored. You can store this certificate anywhere you like. Generally, you are right for the brute force - if the database is restored, you can try to brute force the DMK, when you have it, you can read all encrypted columns. But when you cannot restore the database using its backup, you can do nothing.