TDE的主要作用是防止数据库备份或数据文件被偷了以后,偷数据库备份或文件的人在没有数据加密密钥的情况下是无法恢复或附加数据库的。

首先创建SQL Server中master系统数据库的MASTER KEY和CERTIFICATE:

USE [master];
GO --查看master数据库是否被加密
SELECT name,is_master_key_encrypted_by_server FROM
sys.databases; --创建master数据库下的主数据库密钥
CREATE MASTER KEY ENCRYPTION BY PASSWORD = N'1qaz@WSX3edc$RFV'; --如果创建后要删除master数据库下的主数据库密钥,可以使用下面的语句
--DROP MASTER KEY --查看master数据库下的密钥信息
SELECT * FROM sys.symmetric_keys; --创建证书用来保护 数据库加密密钥 (DEK)
CREATE CERTIFICATE master_server_certficate WITH
SUBJECT = N'Master Protect DEK Certificate'; --如果创建后要删除master数据库下的证书,可以使用下面的语句
--DROP CERTIFICATE master_server_certficate

创建测试数据库TestDbEncryption,该数据库将会开启TDE加密:

CREATE DATABASE TestDbEncryption;

GO

接下来启用数据库TestDbEncryption的DEK 数据库加密密钥 (对称密钥)

USE TestDbEncryption;
GO --创建由master_server_cert保护的DEK 数据库加密密钥 (对称密钥)
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_128
ENCRYPTION BY SERVER CERTIFICATE master_server_certficate; --如果创建后,要删除TestDbEncryption数据库上的DEK 数据库加密密钥,可以使用下面的语句
--DROP DATABASE ENCRYPTION KEY --执行上面的CREATE DATABASE ENCRYPTION KEY语句以后出现:
/*
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.
*/
--提示你,立刻备份证书;这里备份证书,不比制定加密私钥的 对称密钥了.因为他的密钥是通过master数据库的主数据库密钥加密了.

执行上面CREATE DATABASE ENCRYPTION KEY会提示备份master系统数据库的CERTIFICATE,所以接下来我们备份master系统数据库的MASTER KEY和CERTIFICATE:

USE master;
GO --打开数据库连接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV'; --备份master系统数据库的CERTIFICATE
BACKUP CERTIFICATE master_server_certficate TO FILE = 'D:\MSSQL_TDE_Keys\master_server_certficate.cer'
WITH PRIVATE KEY (
FILE = 'D:\MSSQL_TDE_Keys\master_server_certficate.pvk' ,
ENCRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV'); --关闭数据库连接MASTER KEY
CLOSE MASTER KEY
GO USE master;
GO --相应的,我们也备份一下数据库主密钥(master)
--打开数据库连接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV';
BACKUP MASTER KEY TO FILE = 'D:\MSSQL_TDE_Keys\master.cer'
ENCRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV'; --关闭数据库连接MASTER KEY
CLOSE MASTER KEY
GO

之后在SQL Server服务器的D:\MSSQL_TDE_Keys路径下会出现三个文件,保存好这三个文件,如下所示:

下面我们就要开启测试数据库TestDbEncryption的TDE加密了:

USE TestDbEncryption
GO --生产环境下,设置成单用户在运行加密
ALTER DATABASE TestDbEncryption SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO --开启TDE 加密
ALTER DATABASE TestDbEncryption SET ENCRYPTION ON;
GO --设置多用户访问
ALTER DATABASE TestDbEncryption SET MULTI_USER WITH ROLLBACK IMMEDIATE;
GO --再次开启TDE 加密,解释下为什么在上面设置多用户访问后,这里还要执行一次SET ENCRYPTION ON,因为不知道是不是SQL Server的一个BUG,如果只执行上面一次SET ENCRYPTION ON,后面查询SELECT DB_NAME(database_id),encryption_state FROM sys.dm_database_encryption_keys时,encryption_state的值永远为2
ALTER DATABASE TestDbEncryption SET ENCRYPTION ON;
GO

如果开启数据库TestDbEncryption的TDE加密后,之后想要关闭TDE加密,可以使用下面的语句:

USE TestDbEncryption
GO --生产环境下,设置成单用户在运行加密
ALTER DATABASE TestDbEncryption SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO --关闭TDE 加密
ALTER DATABASE TestDbEncryption SET ENCRYPTION OFF;
GO --设置多用户访问
ALTER DATABASE TestDbEncryption SET MULTI_USER WITH ROLLBACK IMMEDIATE;
GO --再次关闭TDE 加密,解释下为什么在上面设置多用户访问后,这里还要执行一次SET ENCRYPTION OFF,因为不知道是不是SQL Server的一个BUG,如果只执行上面一次SET ENCRYPTION OFF,后面查询SELECT DB_NAME(database_id),encryption_state FROM sys.dm_database_encryption_keys时,encryption_state的值永远为5
ALTER DATABASE TestDbEncryption SET ENCRYPTION OFF;
GO

查看TestDbEncryption数据库是否被加密:

--查看TestDbEncryption数据库是否被加密 encryption_state:3 TDE加密了
SELECT DB_NAME(database_id),encryption_state FROM sys.dm_database_encryption_keys;
/*
发现tempdb也被加密了。MSDN解释是:如果实例中有一个数据库启用了TDE加密,那么tempdb也被加密
*/

查询结果为:

这里给出MSDN上列出的encryption_state所有值的含义:

encryption_state
Indicates whether the database is encrypted or not encrypted.

  • 0 = No database encryption key present, no encryption
  • 1 = Unencrypted
  • 2 = Encryption in progress
  • 3 = Encrypted
  • 4 = Key change in progress
  • 5 = Decryption in progress
  • 6 = Protection change in progress (The certificate or asymmetric key that is encrypting the database encryption key is being changed.)

详情可以查看 sys.dm_database_encryption_keys (Transact-SQL)

之后我们先备份已启用TDE的测试数据库TestDbEncryption到数据库备份文件TestDbEncryption.bak:

USE master;
GO --打开数据库连接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD=N'1qaz@WSX3edc$RFV'; BACKUP DATABASE TestDbEncryption
TO DISK='D:\MSSQL_Backup\TestDbEncryption.bak' --关闭数据库连接MASTER KEY
CLOSE MASTER KEY

接下来,找另外一台机器或者实例来测试,如果数据库备份文件被盗走了,防止被还原。这时就要用到我们前面生成的三个文件了:

先在另外一台机器还原MASTER KEY:

USE master;
GO --先在另外一台机器还原了MASTER KEY (该机器master数据库无master key)
RESTORE MASTER KEY
FROM FILE = 'D:\MSSQL_TDE_Keys\master.cer'
DECRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV'
ENCRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV';
GO

再还原CERTIFICATE:

USE master;
GO --打开数据库连接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD=N'1qaz@WSX3edc$RFV';
--创建证书
CREATE CERTIFICATE master_server_certficate
FROM FILE = 'D:\MSSQL_TDE_Keys\master_server_certficate.cer'
WITH PRIVATE KEY (FILE = 'D:\MSSQL_TDE_Keys\master_server_certficate.pvk',
DECRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV');
GO --关闭数据库连接MASTER KEY
CLOSE MASTER KEY

最后使用前面准备的数据库备份文件TestDbEncryption.bak,还原数据库TestDbEncryption:

USE master;
GO --打开数据库连接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD=N'1qaz@WSX3edc$RFV'; RESTORE DATABASE TestDbEncryption FROM DISK='D:\MSSQL_Backup\TestDbEncryption.bak'
WITH MOVE 'TestDbEncryption'
TO 'D:\MSSQL_Data\TestDbEncryption.mdf',
MOVE 'TestDbEncryption_log'
TO 'D:\MSSQL_Log\TestDbEncryption_log.ldf'
GO --关闭数据库连接MASTER KEY
CLOSE MASTER KEY

如果要直接附加启用TDE的数据库mdf和ldf文件到SQL Server,可以采用下面的语句:

USE master;
GO --打开数据库连接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD=N'1qaz@WSX3edc$RFV'; --附加数据库
CREATE DATABASE TestDbEncryption
ON PRIMARY
(
FILENAME=N'C:\Users\Administrator\Desktop\TestDbEncryption.mdf'
)
LOG ON
(
FILENAME=N'C:\Users\Administrator\Desktop\TestDbEncryption_log.ldf'
)
FOR ATTACH ;
GO --关闭数据库连接MASTER KEY
CLOSE MASTER KEY

在还原或附加数据库TestDbEncryption后,最好用下面的语句检查下数据库文件是否有错误:

USE master;
GO --打开数据库连接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD=N'1qaz@WSX3edc$RFV'; DBCC CHECKDB([TestDbEncryption]) WITH NO_INFOMSGS --关闭数据库连接MASTER KEY
CLOSE MASTER KEY

如果DBCC CHECKDB语句没有报错,就没有问题。

所以如果有人盗走数据库备份文件TestDbEncryption.bak,直接拿到另外一台SQL Server服务器上还原,或者直接附加TestDbEncryption.mdf和TestDbEncryption_log.ldf数据库文件到另一台SQL Server,是不行的,会报错。

此外上面很多SQL脚本中使用了OPEN MASTER KEY 和 CLOSE MASTER KEY来打开和关闭MASTER KEY连接,只有像备份还原等这种关键SQL才需要打开和关闭MASTER KEY连接,普通的SELECT、UPDATE、INSERT、DELETE等数据操作SQL语句是不需要打开和关闭MASTER KEY连接的,TDE加密对于数据库用户来说是透明的,不会影响普通SQL语句的使用。

在新的SQL Server服务器或实例还原MASTER KEY和CERTIFICATE后,还需要注意的几个地方:
首先,当你在新的SQL Server服务器或实例还原MASTER KEY和CERTIFICATE后,执行下面的SQL语句:

USE master;
GO --查看master数据库是否被加密
SELECT name,is_master_key_encrypted_by_server FROM
sys.databases;

你会发现master系统数据库的is_master_key_encrypted_by_server为0

这是因为is_master_key_encrypted_by_server表示的是当前SQL Server实例使用的MASTER KEY,是否是在当前SQL Server实例中创建的,很明显由于我们此时的MASTER KEY是通过RESTORE MASTER KEY语句还原得到的,所以不是由当前SQL Server实例创建的,因此master系统数据库的is_master_key_encrypted_by_server为0.

MSDN上对is_master_key_encrypted_by_server的解释如下:

The is_master_key_encrypted_by_server column of the sys.databases catalog view in master indicates whether the database master key is encrypted by the service master key.

详情可以查看 CREATE MASTER KEY (Transact-SQL)

当前SQL Server实例master系统数据库的is_master_key_encrypted_by_server为0,会引出下一个问题,那就是当前SQL Server实例中新的数据库都无法成功开启TDE,例如我们现在创建一个数据库Demo

CREATE DATABASE Demo

你会发现按照我们前面介绍的方法开启数据库Demo的TDE后,执行如下查询

--查看TestDbEncryption数据库是否被加密 encryption_state:3 TDE加密了
SELECT DB_NAME(database_id),encryption_state FROM sys.dm_database_encryption_keys;

结果Demo的encryption_state始终为2:

这就是因为master系统数据库的is_master_key_encrypted_by_server为0导致的。

所以当在新的SQL Server服务器或实例上还原或附加TestDbEncryption数据库后,我们应该重建新的SQL Server服务器或实例的MASTER KEY和CERTIFICATE

因此当还原或附加TestDbEncryption数据库后,我们首先应该关闭TestDbEncryption数据库的TDE加密,如下SQL语句所示:

USE TestDbEncryption
GO --生产环境下,设置成单用户在运行加密
ALTER DATABASE TestDbEncryption SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO --关闭TDE 加密
ALTER DATABASE TestDbEncryption SET ENCRYPTION OFF;
GO --设置多用户访问
ALTER DATABASE TestDbEncryption SET MULTI_USER WITH ROLLBACK IMMEDIATE;
GO --再次关闭TDE 加密,解释下为什么在上面设置多用户访问后,这里还要执行一次SET ENCRYPTION OFF,因为不知道是不是SQL Server的一个BUG,如果只执行上面一次SET ENCRYPTION OFF,后面查询SELECT DB_NAME(database_id),encryption_state FROM sys.dm_database_encryption_keys时,encryption_state的值永远为5
ALTER DATABASE TestDbEncryption SET ENCRYPTION OFF;
GO

接着删除数据库TestDbEncryption的DEK 数据库加密密钥 (对称密钥)

USE TestDbEncryption;
GO --如果创建后,要删除TestDbEncryption数据库上的DEK 数据库加密密钥,可以使用下面的语句
DROP DATABASE ENCRYPTION KEY

然后删除当前SQL Server中master系统数据库的MASTER KEY和CERTIFICATE

USE [master]
GO --如果创建后要删除master数据库下的证书,可以使用下面的语句
DROP CERTIFICATE master_server_certficate
GO --如果创建后要删除master数据库下的主数据库密钥,可以使用下面的语句
DROP MASTER KEY
GO

重新创建SQL Server中master系统数据库的MASTER KEY和CERTIFICATE

USE [master]
GO --创建master数据库下的主数据库密钥
CREATE MASTER KEY ENCRYPTION BY PASSWORD = N'1qaz@WSX3edc$RFV';
GO --创建证书用来保护 数据库加密密钥 (DEK)
CREATE CERTIFICATE master_server_certficate WITH
SUBJECT = N'Master Protect DEK Certificate';
GO

这时再查询

USE [master];
GO --查看master数据库是否被加密
SELECT name,is_master_key_encrypted_by_server FROM
sys.databases;

我们就会发现master系统数据库的is_master_key_encrypted_by_server为1了

原因就是我们现在通过新的SQL Server服务器或实例,重新创建了master系统数据库的MASTER KEY和CERTIFICATE

接着和前面一样记住备份新创建的MASTER KEY和CERTIFICATE

USE master;
GO --打开数据库连接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV'; --备份master系统数据库的CERTIFICATE
BACKUP CERTIFICATE master_server_certficate TO FILE = 'D:\MSSQL_TDE_Keys\master_server_certficate.cer'
WITH PRIVATE KEY (
FILE = 'D:\MSSQL_TDE_Keys\master_server_certficate.pvk' ,
ENCRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV'); --关闭数据库连接MASTER KEY
CLOSE MASTER KEY
GO USE master;
GO --相应的,我们也备份一下数据库主密钥(master)
--打开数据库连接MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV';
BACKUP MASTER KEY TO FILE = 'D:\MSSQL_TDE_Keys\master.cer'
ENCRYPTION BY PASSWORD = '1qaz@WSX3edc$RFV'; --关闭数据库连接MASTER KEY
CLOSE MASTER KEY
GO

最后按照本文前面说的方法,开启新的SQL Server服务器或实例上各个数据库的TDE加密就行了,这时新的SQL Server服务器或实例上的数据库应该都可以成功开启TDE加密了,开启后查询

--查看TestDbEncryption数据库是否被加密 encryption_state:3 TDE加密了
SELECT DB_NAME(database_id),encryption_state FROM sys.dm_database_encryption_keys;

encryption_state都应该为3了

SQLServer的TDE加密的更多相关文章

  1. (转)笔记320 SQLSERVER中的加密函数 2013-7-11

    1 --SQLSERVER中的加密函数 2013-7-11 2 ENCRYPTBYASYMKEY() --非对称密钥 3 ENCRYPTBYCERT() --证书加密 4 ENCRYPTBYKEY() ...

  2. sqlserver 进行MD5加密

    官方定义函数: HashBytes ( '<algorithm>', { @input | 'input' } )  <algorithm>::= MD2 | MD4 | MD ...

  3. SQLSERVER使用密码加密备份文件以防止未经授权还原数据库

    原文:SQLSERVER使用密码加密备份文件以防止未经授权还原数据库 SQLSERVER使用密码加密备份文件以防止未经授权还原数据库 在备份数据库的时候,用户可以为媒体集.备份集或两者指定密码 在ba ...

  4. SQL SERVER 2008 使用TDE加密和解密

    SQL SERVER 2008 加密和解密,这样的文件在互联网上不胜枚举,本文的寓意还是一样,一为记录,二可以为开发者提供在实现过程中的注意事项. TDE: Transparent data encr ...

  5. 解密TDE加密数据库

    1 找到加密的数据库,new query 2 执行sql 语句:ALTER DATABASE  database_name SET ENCRYPTION OFF; DROP DATABASE ENCR ...

  6. mssql sqlserver 视图如何加密,让第三方用户查看不到其中的SQL语句

    转自:http://www.maomao365.com/?p=6719 摘要: 下文讲述视图加密的方法分享,通过此方法可以使视图只可使用,无法获取视图中sql脚本的内容,如下所示: 在创建视图的语法中 ...

  7. SQLServer · 最佳实践 · 透明数据加密TDE在SQLServer的应用

    转:https://yq.aliyun.com/articles/42270 title: SQLServer · 最佳实践 · 透明数据加密TDE在SQLServer的应用 author: 石沫 背 ...

  8. [转]细说SQL Server中的加密

    简介 加密是指通过使用密钥或密码对数据进行模糊处理的过程.在SQL Server中,加密并不能替代其他的安全设置,比如防止未被授权的人访问数据库或是数据库实例所在的Windows系统,甚至是数据库所在 ...

  9. SQL Server 2014新特性-原生备份加密

    注:本篇文章是IT68找我的约稿,原文地址:http://tech.it168.com/a2014/0610/1633/000001633147.shtml       SQL Server 2014 ...

随机推荐

  1. Maven 打包遇到的问题

    [ERROR] No compiler is provided in this environment. Perhaps you are running on a JRE rather than a ...

  2. tomcat关闭后线程依然运行解决办法

    tomcat关闭后线程依然运行解决办法,设置线程为守护线程 守护线程与非守护线程 最近在看多线程的Timer章节,发现运用到了守护线程,感觉Java的基础知识还是需要补充. Java分为两种线程:用户 ...

  3. Tomcat学习总结(14)—— Tomcat常见面试题

    一.Tomcat的缺省是多少,怎么修改 Tomcat的缺省端口号是8080. 修改Tomcat端口号: 1.找到Tomcat目录下的conf文件夹 2.进入conf文件夹里面找到server.xml文 ...

  4. mysql进行时

    1. 安装 参考 2. 远程连不上数据库 远程连接mysql时,提示“is not allowed to connect to this MySQL server” 解决(授权法): GRANT AL ...

  5. GCD之同步异步

    博客地址:http://blog.csdn.net/chaoyuan899/article/details/12554603

  6. ASP.NET MVC提交一个较复杂对象至WCF Service

    前一篇<jQuery.Ajax()执行WCF Service的方法>http://www.cnblogs.com/insus/p/3727875.html 我们有练习在asp.net mv ...

  7. MVC应用程序播放RealPlayer(rmvb)视频

    以前Insus.NET开发asp.net时,一直无法把Realplayer的rmvb格式的视频在aspx网页播放与显示.现在学习ASP.NET MVC了,再次尝试这个,望它能在MVC的应用程序运行. ...

  8. oracle逐步学习总结之oracle数字函数和日期函数(基础四)

    原创作品,转自请注明出处:https://www.cnblogs.com/sunshine5683/p/10140716.html 继上篇总结,继续进行总结: 以下下数字函数: 1.abs(n):返回 ...

  9. Redis——非阻塞IO和队列

    Redis是个高并发的中间件,但是确实是单线程.而且,Nginx.Node.js等也是单线程的.Redis通过非阻塞IO(IO多路复用)处理那么多的并发客户端连接,并且,由于Redis所有的数据都在内 ...

  10. Android-加载图片避免OOM

    http://blog.csdn.net/guolin_blog/article/details/9316683 高效加载大图片 我们在编写Android程序的时候经常要用到许多图片,不同图片总是会有 ...