Here is my scenario:
I restored a database R to a QA SQL Server and renamed to to Rtest. There is another instance of database R on the server.
I ran the following commands to enable encryption:
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'ABC'
RESTORE MASTER KEY FROM FILE = 'ThePath'
DECRYPTION BY PASSWORD = 'DEF'
ENCRYPTION BY PASSWORD = 'GHI'
If I connect to the database as the SysAdmin I am able to decrypt the column that is encrypted. queries work just fine.
If I connect to the database as a local user I get the following error:
Msg 15581, Level 16, State 3, Line 2
Please create a master key in the database or open the master key in the session before performing this operation.
While logged in as the local user I run the following:
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'ABC'
I am able to run queries for the connection but once I open up a new connection I am back to getting the error.
The only way I have been able to consistently run the queries is to run the following command every time access to the encrypted column is desired:
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'ABC'
Basically I have to do the following each time I want to select, update, or insert to the table:
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'ABC'
select EncryptedColumn from TableA where x = 2
I am trying to figure out why I have to keep opening up the Master Key every time. Usually I just run the command once and then that is it. Any help would be appreciated. Thank you.
You need to add the DMK into the System database:
OPEN MASTER KEY
DECRYPTION BY PASSWORD = '# this is a 123 strong password';
ALTER MASTER KEY
ADD ENCRYPTION BY SERVICE MASTER KEY;
This will allow SQL server to auto open the Database master key automatically when needed.
http://msdn.microsoft.com/en-us/library/ms186937(v=sql.90).aspx
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
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?
Two years ago, I used the below code to encrypt (TDE) the database in SQL Server 2008
USE MASTER;
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Strong Password'
GO
USE MASTER;
CREATE CERTIFICATE DB_CER WITH SUBJECT = 'DB Certificate'
GO
USE DB
GO
CREATE DATABASE ENCRYPTION KEY WITH
ALGORITHM = AES_256 ENCRYPTION BY
SERVER CERTIFICATE DB_CER ;
GO
USE DB
ALTER DATABASE DB
SET ENCRYPTION ON ;
GO
USE master;
GO
BACKUP CERTIFICATE DB_CER
TO FILE = 'c:\Backup\certificate_DB_Certificate.cer'
WITH PRIVATE KEY
(FILE = 'c:\Backup\certificate_DB_Key.pvk',
ENCRYPTION BY PASSWORD = 'Strong Password')
I took full backup for DB Database and the certificate_DB_Certificate.cer & certificate_DB_Key.pvk and save it to my hard drive.
After two years I used different PC to restore the MASTER KEY & the CERTIFICATE, so I can to restore the Backup file
CREATE CERTIFICATE DB_CER
FROM FILE = 'D:\Backup\certificate_DB_Certificate.cer'
WITH PRIVATE KEY (FILE = 'D:\Backup\certificate_OCV_DB_Key.pvk',
DECRYPTION BY PASSWORD = 'Strong Password')
After I run the code I got this message
Warning: The certificate you created is expired.
So I delete the CERTIFICATE and I change the Pc date to 2015/Jun (the date when The CERTIFICATE was created) then I re-create the certificate again with successfully completed command, but when I restore the backup file I got this message
Restore of database 'DB' failed.
(Microsoft.SqlServer.Management.RelationalEngineTasks)
System.Data.SqlClient.SqlError: Cannot find server certificate with thumbprint '0xFC01AD2683E08A4C8CD6A0F037DC66A945FBA44D'. (Microsoft.SqlServer.SmoExtended)
Any suggestions?
The "expired certificate" message was a warning, not an error. You can still use an expired certificate.
Delete the certificate you created with the changed date, then restore the certificate again with the correct date.
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.
I have a database that was moved off of an old SQL Server 2008R2 instance and into a SQL Server 2012 AlwaysOn cluster. There are several fields within the database that are encrypted using SQL Servers built-in encryption features (master key, cert, symmetric key.)
I have run the following commands on my QA AO instance (the same steps that had been run on the old server):
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'password'
CREATE CERTIFICATE myCert
WITH SUBJECT = 'password'
CREATE SYMMETRIC KEY myKeyName
WITH ALGORITHM = TRIPLE_DES
ENCRYPTION BY CERTIFICATE myCert
Additionally I had to run the following commands to correctly decrypt the data:
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'password'
ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY
When I run this command I then see all of the data decrypted:
OPEN SYMMETRIC KEY myKeyName
DECRYPTION BY CERTIFICATE myCert
select TOP 1000 userid, CONVERT(nVARCHAR(255),DECRYPTBYKEY(password)) from users
CLOSE SYMMETRIC KEY myKeyName
So far so good. However, if I run these same steps on my production AO cluster this query:
select TOP 1000 userid, CONVERT(nVARCHAR(255),DECRYPTBYKEY(password)) from users
returns NULL for the password. To make this a little bit more maddening, this statement (run in the context of the QA environment) decrypts everything from both databases just fine:
OPEN SYMMETRIC KEY myKeyName
DECRYPTION BY CERTIFICATE myCert
SELECT TOP 1000
userid,
CONVERT(nVARCHAR(255),DECRYPTBYKEY(password))
FROM users
SELECT TOP 1000
userid,
CONVERT(nVARCHAR(255),DECRYPTBYKEY(password))
FROM PRODUCTIONAO.prod_database.dbo.users
CLOSE SYMMETRIC KEY myKeyName
I am not sure why this would work on my QA instance, but not on my production instance. Any help would be greatly appreciated!
The reason your last query works is due to the fact that you're using the QA instance's key/cert to do the decryption of the production data. In QA you can auto-decrypt the cert with the database master key (DMK) since it's encrypted by the QA service master key (SMK) as follows:
Service Master Key (QA)
Database Master Key (QA)
Certificate (QA)
Symmetric Key (QA)
Data (Prod)
In prod, you have a different SMK so the only option to open the DMK is by using the password. It seems that you ran the following in the QA environment but not in prod:
/* Add service master key encryption to the database master key */
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'password'
ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY
Try this in prod:
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'password'
OPEN SYMMETRIC KEY myKeyName
DECRYPTION BY CERTIFICATE myCert
select TOP 1000 userid, CONVERT(nVARCHAR(255),DECRYPTBYKEY(password)) from users
CLOSE SYMMETRIC KEY myKeyName
If that returns data, you need to add the SMK encryption to your DMK in production (the first script). The other option is backing up the SMK from the source instance and restoring it on the secondary. I'd only recommend this in HA use-cases where the instances are fail-over partners and both are in the same environment. Sharing SMKs between QA and prod is a bad practice.
When a database master key is created, the server saves 2 versions of key. One version is encrypted by the master service key and by default is used by the server. The second version is encrypted by the password that you supply to the server when you create the database master key. This version usually is not used. When you move your database into a different environment (production in your case), the new server has a different master service key. Since it is not the service key that was used to encrypt the database’s master key, it also can’t be used in order to open the database’s master key. This is where you should use the version that was encrypted with your password. You need to open the master key using your password, then encrypt it using the new service key and close it. After you do that, the database’s master key can work with the master service key, so you don’t need to do it again.
steps/code:
open master key decryption by password = 'WriteYouOriginalPasswordHere'
alter master key add encryption by service master key
close master key