一、测试TDE
此部分内容扩展SQL Server安全系列的第九篇:SQL Server安全透明数据加密的测试TDE章节。启用TDE的详细步骤请参考原文。

-- Create a test database
CREATE DATABASE UestDB
GO
-- Create a certificate in master to use with TDE
USE master;
GO
-- TDE hooks into encryption key hierarchy in SQL Server
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '!drJP9QXC&Vi%cs';
GO
-- Create the certificate used to protect the database encryption key
CREATE CERTIFICATE UestDBTDECert WITH SUBJECT = 'Certificate to implement TDE on UestDB';
GO -- Backup the master_key
BACKUP MASTER KEY TO FILE = 'D:\SQL2012\MasterKey.bak' ENCRYPTION BY PASSWORD = 'pass';
GO
-- Backup the certificate
-- Either create the D:\SQL2012 folder or change it in the code below
BACKUP CERTIFICATE UestDBTDECert TO FILE = 'D:\SQL2012\UestDBTDECert'
WITH PRIVATE KEY ( FILE = 'D:\SQL2012\UestDBTDECertPrivateKey' ,
ENCRYPTION BY PASSWORD = 'RISiS9Ul%CByEk6' );
GO
-- Must backup private key as well

代码1 创建主密钥、证书并备份主密钥、证书

USE UestDB;
GO
-- Create the database encryption key for TDE. Analogous to database master key for data encryption.
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = TRIPLE_DES_3KEY
ENCRYPTION BY SERVER CERTIFICATE UestDBTDECert;
GO
-- Get a warning about backing up the key, if you haven't already
-- ...take the advice and back it up! -- Now need to turn TDE on.
ALTER DATABASE UestDB SET ENCRYPTION ON;
GO

代码2 创建数据库加密密钥并启用TDE
接下来模拟证书和主库密钥丢失的情况
->1 del master_key + certificate
->2 create master_key + certificate
->3 create master_key + restore certificate
->4 restore master_key + certificate
首先备份UestDB数据库

--backup test database
BACKUP DATABASE UestDB
TO DISK = N'D:\SQL2012\MSSQL11.SQL12\MSSQL\Backup\UestDB.bak'
WITH NOFORMAT, INIT, NAME = N'UestDB Full Database Backup',
SKIP, NOREWIND, NOUNLOAD, COMPRESSION, STATS = 10;
GO

代码3 备份数据库
1、删除证书、删除master_key+重启数据库服务

USE master
GO
-- Oops! We lost the certificate and don't have a copy!
-- Or, going to restore the database to another server instance
DROP CERTIFICATE UestDBTDECert;
GO
DROP MASTER KEY;
GO

证书'UestDBTDECert'是由主密钥加密的,因此需先删除证书才能删除master_key。重启数据库服务后在对象资源管理器下展开UestDB数据报错:


图1 UestDB不能访问
查看ERRORLOG日志如下所示:

图2 删除证书、删除master_key
2、用源代码重新创建master_key、创建证书+重启数据库服务

-- Create a certificate in master to use with TDE
USE master;
GO
-- TDE hooks into encryption key hierarchy in SQL Server
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '!drJP9QXC&Vi%cs';
GO
-- Create the certificate used to protect the database encryption key
CREATE CERTIFICATE UestDBTDECert WITH SUBJECT = 'Certificate to implement TDE on UestDB';
GO

重启数据库服务后,UestDB库依然不能访问,ERRORLOG日志如下所示:

图3 重新创建master_key、创建证书
3、用源代码重新创建master_key、还原证书+重启数据库服务

-- Clean up
USE master;
GO
DROP CERTIFICATE UestDBTDECert;
GO
DROP MASTER KEY;
GO
-- TDE hooks into encryption key hierarchy in SQL Server
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '!drJP9QXC&Vi%cs';
GO
-- Restore the certificate
CREATE CERTIFICATE UestDBTDECert
FROM FILE = 'D:\SQL2012\UestDBTDECert'
WITH PRIVATE KEY ( FILE = 'D:\SQL2012\UestDBTDECertPrivateKey',
DECRYPTION BY PASSWORD = 'RISiS9Ul%CByEk6');

重启数据库服务后,UestDB数据库能正常访问(实际上创建mater_key使用其他密码也可以,总结来说就是证书一定要有备份),ERRORLOG日志如下所示:

图4 重新创建master_key、还原证书
4、还原master_key、还原证书+重启数据库服务

-- Clean up
USE master;
GO
DROP CERTIFICATE UestDBTDECert;
GO
DROP MASTER KEY;
GO
-- Restore the master_key
RESTORE MASTER KEY FROM FILE='D:\SQL2012\MasterKey.bak'
DECRYPTION BY PASSWORD ='pass'--备份数据库主密钥时指定的密码
ENCRYPTION BY PASSWORD ='newpass'--数据库主密钥使用的新密码,除非重新应用Service Master Key的加密,否则需使用此密码显示打开和关闭数据库主密钥)
GO
--打开数据库主密钥
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'newpass'
-- Restore the certificate
CREATE CERTIFICATE UestDBTDECert
FROM FILE = 'D:\SQL2012\UestDBTDECert'
WITH PRIVATE KEY ( FILE = 'D:\SQL2012\UestDBTDECertPrivateKey',
DECRYPTION BY PASSWORD = 'RISiS9Ul%CByEk6');
--关闭数据库主密钥
CLOSE MASTER KEY

ERRORLOG日志如下所示:

图5 还原master_key、还原证书(未应用Service Master Key的加密)
“在执行此操作之前,请在数据库中创建一个主密钥或在会话中打开该主密钥。”此时UestDB数据库不能访问,想想在我们创建证书的时候如果没有用密码打开master key也会报这样的错,这是由于还原出来master key只使用了密码加密,而没有使用Service Master Key加密。因此对于相关的密钥、证书操作都要先使用OPEN MASTER KEY。下面我们在还原master key之后,重新应用Service Master Key的加密

-- Clean up
USE master;
GO
DROP CERTIFICATE UestDBTDECert;
GO
DROP MASTER KEY;
GO
-- Restore the master_key
RESTORE MASTER KEY FROM FILE='D:\SQL2012\MasterKey.bak'
DECRYPTION BY PASSWORD ='pass'--备份数据库主密钥时指定的密码
ENCRYPTION BY PASSWORD ='newpass'--数据库主密钥使用的新密码,除非重新应用Service Master Key的加密,否则需使用此密码显示打开和关闭数据库主密钥)
GO
--打开数据库主密钥
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'newpass'
--重新应用Service Master Key的加密
ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY--执行后,数据库主密钥不再需要被显式打开或关闭,拥有足够许可(如sysadmin)的用户自动使用数据库主密钥解密
--关闭数据库主密钥
CLOSE MASTER KEY
-- Restore the certificate
CREATE CERTIFICATE UestDBTDECert
FROM FILE = 'D:\SQL2012\UestDBTDECert'
WITH PRIVATE KEY ( FILE = 'D:\SQL2012\UestDBTDECertPrivateKey',
DECRYPTION BY PASSWORD = 'RISiS9Ul%CByEk6');

ERRORLOG日志如下所示:

图6 还原master_key、还原证书(重新应用Service Master Key的加密)
意外收获:在自己电脑上测试,频繁重启数据库服务,导致SSMS卡死,相关代码却没有保存。等待一段时候SSMS还是未响应:

图7 SSMS未响应
到相关目录寻找是否有临时文件保存了代码

图8 C:\Users\Administrator\Documents\SQL Server Management Studio\Backup Files\Solution1
第二天打开SSMS提示

图9
点击恢复选定的文件,到相应目录查找C:\Users\Administrator\AppData\Local\Temp

图10
算是幸运,文件在当时已经找到。还是要养成随时保存脚本的习惯!
二、列数据加密
此部分内容扩展SQL Server安全系列的第八篇:SQL Server安全数据加密。列数据加密的详细步骤请参考原文。本节重点关注列数据加密迁移及非对称密钥和对称密钥的修改。
首先,我们继续使用本篇第一部分创建的UestDB数据库,创建测试使用的表:

USE UestDB
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[LoginsInfo]') AND type in (N'U'))
DROP TABLE [dbo].[LoginsInfo]
GO
CREATE TABLE [LoginsInfo](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Item] [varchar](20) NULL,
[LoginName] [varchar](30) NULL,
[PassWords] [varbinary](1000) NULL,
[Notes] [varbinary](1000) NULL,--alter(varchar->varbinary)
[BindingMail] [varchar](50) NULL,--add column
[ULR] [varchar](50) NULL,
[CType] [tinyint] NULL,
[InsertTime] [datetime] NULL,
CONSTRAINT [PK_LoginsInfo] PRIMARY KEY CLUSTERED([Id] ASC)
)
GO
ALTER TABLE [dbo].[LoginsInfo] ADD CONSTRAINT [DF_LoginsInfo_InserTime] DEFAULT (getdate()) FOR [InsertTime]
GO

创建Database Master Key,并备份master_key

USE UestDB;
GO
--数据库主密钥创建时默认使用Service Master Key和CREATE MASTER KEY中的密码加密
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'gK#3hbQKDFQY0oF';
GO
--Backup the DatabaseMasterKey
BACKUP MASTER KEY TO FILE = 'D:\SQL2012\UestDBMasterKey.bak' ENCRYPTION BY PASSWORD = 'masterkeybakpwd';
GO

创建非对称密钥,只指定了算法,没有指定PASSWORD子句,默认会使用Database Master Key加密私钥,这也是前面要创建Database Master Key的原因。接着创建对称密钥,使用前面的非对称密钥来加密,注意指定KEY_SOURCE和IDENTITY_VALUE

-- Create an asymmetric key to protect the new symmetric key
CREATE ASYMMETRIC KEY UestAsymmetricKey --名称
--AUTHORIZATION Uest --所有者(数据库用户、数据库角色)
WITH ALGORITHM = RSA_2048 --算法
-- 没有指定PASSWORD子句,则用数据库master key加密私钥
-- Create a symmetric key, protected by the asymmetric key
CREATE SYMMETRIC KEY UestSymmetricKey --名称
WITH KEY_SOURCE ='pass_phrase', --derive the key
ALGORITHM = TRIPLE_DES, --算法
IDENTITY_VALUE = 'identity_phrase' --generate a GUID
ENCRYPTION BY ASYMMETRIC KEY UestAsymmetricKey;--加密机制

使用对称密钥对数据进行加密

-- 打开对称密钥
OPEN SYMMETRIC KEY UestSymmetricKey
DECRYPTION BY ASYMMETRIC KEY UestAsymmetricKey
INSERT INTO LoginsInfo(Item,LoginName,PassWords,Notes,BindingMail,ULR,CType)
VALUES ('QQ', '',EncryptByKey(Key_GUID('UestSymmetricKey'), 'Pass1')
,EncryptByKey(Key_GUID('UestSymmetricKey') ,'The first and the last letter is capitalized')
,'1234567@qq.com','http://qzone.qq.com/',1);
-- 关闭对称密钥
CLOSE SYMMETRIC KEY UestSymmetricKey;

查看原始数据和解密数据

-- 查看数据
OPEN SYMMETRIC KEY UestSymmetricKey
DECRYPTION BY ASYMMETRIC KEY UestAsymmetricKey
SELECT Id, Item, LoginName,
CONVERT(VARCHAR, DecryptByKey(PassWords)) AS PassWords,
CONVERT(VARCHAR, DecryptByKey(Notes)) AS Notes,
BindingMail,ULR,Ctype
FROM LoginsInfo;
CLOSE SYMMETRIC KEY UestSymmetricKey;


从结果可以看到存储在表中的PassWords字段已加密,需使用对应的密钥解密才能看到真实数据。
列数据加密如何迁移
假如现在需要将LoginsInfo表中的数据导入到另一个库/另一个实例下的一张数据表中,导过去后如何查看真实数据?

DROP TABLE DBA_Monitor.dbo.LoginsInfo
SELECT *
INTO DBA_Monitor.dbo.LoginsInfo
FROM LoginsInfo

可以通过导入/导出、select...into...等多种方式将数据转移到其他表。用源代码在目标数据库创建相同的非对称密钥和对称密钥

USE DBA_Monitor;
GO
--数据库主密钥创建时默认使用Service Master Key和CREATE MASTER KEY中的密码加密
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'gK#3hbQKDFQY0oF';
GO
-- Create an asymmetric key to protect the new symmetric key
CREATE ASYMMETRIC KEY UestAsymmetricKey --名称
--AUTHORIZATION Uest --所有者(数据库用户、数据库角色)
WITH ALGORITHM = RSA_2048 --算法
-- 没有指定PASSWORD子句,则用数据库master key加密私钥
-- Create a symmetric key, protected by the asymmetric key
CREATE SYMMETRIC KEY UestSymmetricKey --名称
WITH KEY_SOURCE ='pass_phrase', --derive the key
ALGORITHM = TRIPLE_DES, --算法
IDENTITY_VALUE = 'identity_phrase' --generate a GUID
ENCRYPTION BY ASYMMETRIC KEY UestAsymmetricKey;--加密机制

MASTER KEY中的PASSWORD不一定要和原来的一样,但是对称密钥中的KEY_SOURCE和IDENTITY_VALUE必须与原来的保持一样。查看目标表中的数据

USE DBA_Monitor;
GO
-- 查看数据
OPEN SYMMETRIC KEY UestSymmetricKey
DECRYPTION BY ASYMMETRIC KEY UestAsymmetricKey
SELECT Id, Item, LoginName,
CONVERT(VARCHAR, DecryptByKey(PassWords)) AS PassWords,
CONVERT(VARCHAR, DecryptByKey(Notes)) AS Notes,
BindingMail,ULR,Ctype
FROM LoginsInfo;
CLOSE SYMMETRIC KEY UestSymmetricKey;


至此在新环境中已经能够正常查看加密数据。
修改Database Master Key、非对称密钥和对称密钥
Database Master Key的修改和还原

--重新生成数据库主密钥
ALTER MASTER KEY REGENERATE WITH ENCRYPTION BY PASSWORD ='password'
GO
--删除Service Master Key的加密
ALTER MASTER KEY DROP ENCRYPTION BY SERVICE MASTER KEY--执行后,任何数据库主密钥的修改需要使用OPEN MASTER KEY访问
--使用密码打开数据库主密钥
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'password'
--重新应用Service Master Key的加密
ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY--执行后,数据库主密钥不再需要被显式打开或关闭,拥有足够许可(如sysadmin)的用户自动使用数据库主密钥解密
--关闭数据库主密钥
CLOSE MASTER KEY -- Restore the DatabaseMasterKey
RESTORE MASTER KEY FROM FILE='D:\SQL2012\UestDBMasterKey.bak'
DECRYPTION BY PASSWORD ='masterkeybakpwd'--备份数据库主密钥时指定的密码
ENCRYPTION BY PASSWORD ='openpassword'--还原后数据库主密钥使用的密码(如果删除Service Master Key,则需使用此密码打开数据库主密钥)
GO

修改非对称密钥

/****修改非对称密钥****/
--修改私钥加密方式
ALTER ASYMMETRIC KEY UestAsymmetricKey--要修改的密钥名称
WITH PRIVATE KEY --私钥
(ENCRYPTION BY PASSWORD = 'AsymPass!')--指定密码加密私钥;执行后,与数据库master key就没有关联,此时drop master key不会报错 -- 查看数据
OPEN SYMMETRIC KEY UestSymmetricKey
DECRYPTION BY ASYMMETRIC KEY UestAsymmetricKey
WITH PASSWORD ='AsymPass!';--先用私钥密码打开对称密钥
SELECT Id, Item, LoginName,
CONVERT(VARCHAR, DecryptByKey(PassWords)) AS PassWords,
Notes,ULR,Ctype
FROM LoginsInfo;
CLOSE SYMMETRIC KEY UestSymmetricKey; --修改私钥密码
ALTER ASYMMETRIC KEY UestAsymmetricKey--要修改的密钥名称
WITH PRIVATE KEY --私钥
(ENCRYPTION BY PASSWORD = 'NewAsymPass',--指定新密码
DECRYPTION BY PASSWORD = 'AsymPass!')--旧密码是用来解密的 -- 查看数据
OPEN SYMMETRIC KEY UestSymmetricKey
DECRYPTION BY ASYMMETRIC KEY UestAsymmetricKey
WITH PASSWORD ='NewAsymPass';--先用私钥密码打开对称密钥
SELECT Id, Item, LoginName,
CONVERT(VARCHAR, DecryptByKey(PassWords)) AS PassWords,
Notes,ULR,Ctype
FROM LoginsInfo;
CLOSE SYMMETRIC KEY UestSymmetricKey;

修改对称密钥

/****修改对称密钥的加密方式****/
--先用私钥密码打开对称密钥
OPEN SYMMETRIC KEY UestSymmetricKey
DECRYPTION BY ASYMMETRIC KEY UestAsymmetricKey
WITH PASSWORD ='NewAsymPass';
--打开之后,先增加密码加密,取代原密钥
ALTER SYMMETRIC KEY UestSymmetricKey
ADD ENCRYPTION BY PASSWORD ='SysPass!'
--再删除非对称密钥加密
ALTER SYMMETRIC KEY UestSymmetricKey
DROP ENCRYPTION BY ASYMMETRIC KEY UestAsymmetricKey --执行后,与非对称密钥没有关联,此时DROP ASYMMETRIC KEY不会报错
--完成操作后,关闭对称密钥
CLOSE SYMMETRIC KEY UestSymmetricKey -- 查看数据
OPEN SYMMETRIC KEY UestSymmetricKey
DECRYPTION BY PASSWORD ='SysPass!';--直接用密码打开对称密钥
SELECT Id, Item, LoginName,
CONVERT(VARCHAR, DecryptByKey(PassWords)) AS PassWords,
Notes,ULR,Ctype
FROM LoginsInfo;
CLOSE SYMMETRIC KEY UestSymmetricKey;
-- *** Clean up ***
-- ****************
USE DBA_Monitor
GO
DROP SYMMETRIC KEY UestSymmetricKey
DROP ASYMMETRIC KEY UestAsymmetricKey
DROP MASTER KEY
GO
USE master;
GO
IF DB_ID('UestDB') IS NOT NULL DROP DATABASE UestDB;
GO
-- Can't turn off TDE in tempdb once it is on
DROP CERTIFICATE UestDBTDECert;
GO
DROP MASTER KEY;
GO

此部分主要是查看Database Master Key、非对称密钥和对称密钥的加密方式

TDE与列级数据加密的更多相关文章

  1. sql中表级约束和列级约束

    sql中表级约束和列级约束,在SQL SERVER中, (1) 对于基本表的约束分为列约束和表约束约束是限制用户输入到表中的数据的值的范围,一般分为列级约束与表级约束.列级约束有六种:主键Primar ...

  2. MySQL表级约束和列级约束

    对一个数据列建立的约束,称为列级约束 对多个数据列建立的约束,称为表级约束 列级约束即可以在列定义时生命,也可以在列定义后声明. 表级约束只能在列定义后声明. NOT NULL和DEFAULT只存在列 ...

  3. MySQL进阶13--常见六大约束: 非空/默认/主键/唯一约束/检查约束/外键约束--表级约束 / 列级约束

    /* MySQL进阶13 常见六大约束: 1.not null 非空 2.default :默认值,用于保证该字段的默认值 ; 比如年龄:1900-10-10 3.primary key : 主键,用 ...

  4. Oracle表级约束和列级约束

    Oracle表级约束和列级约束 1. 表级定义约束 指的是在定义完一个表所有列之后,再去定义所有相关的约束. 注意:not null 约束只能在列级上定义. 2. 列级定义约束 指的是在定义一个表的每 ...

  5. 第九篇 SQL Server安全透明数据加密

    本篇文章是SQL Server安全系列的第九篇,详细内容请参考原文. Relational databases are used in an amazing variety of applicatio ...

  6. 【译】第九篇 SQL Server安全透明数据加密

    本篇文章是SQL Server安全系列的第九篇,详细内容请参考原文. Relational databases are used in an amazing variety of applicatio ...

  7. SQL Server安全(9/11):透明数据加密(Transparent Data Encryption)

    在保密你的服务器和数据,防备当前复杂的攻击,SQL Server有你需要的一切.但在你能有效使用这些安全功能前,你需要理解你面对的威胁和一些基本的安全概念.这篇文章提供了基础,因此你可以对SQL Se ...

  8. Oracle数据安全解决方案(1)——透明数据加密TDE

    Oracle数据安全解决方案(1)——透明数据加密TDE2009年09月23日 22:49:00 华仔爱技术 阅读数:7991原文地址: http://www.oracle.com/technolog ...

  9. 透明数据加密 (TDE)常见问题解答

    透明数据加密 (TDE)常见问题解答问题任何人只要有权访问加密数据就能对其进行解密吗?TDE 会带来哪些开销?哪些加密算法可与 TDE 一同使用?可以使用第三方加密算法代替 TDE 提供的算法吗?可以 ...

随机推荐

  1. ORACLE SEQUENCE用法

    引用自: http://www.cnblogs.com/hyzhou/archive/2012/04/12/2444158.html 在oracle中sequence就是序号,每次取的时候它会自动增加 ...

  2. 典型Event ID

    Sr no Event ID 2003 Server Event ID 2008 Server Event Type 1 528 4624 Local User logon 2 6008 6008 U ...

  3. Apache Spark源码走读之1 -- Spark论文阅读笔记

    欢迎转载,转载请注明出处,徽沪一郎. 楔子 源码阅读是一件非常容易的事,也是一件非常难的事.容易的是代码就在那里,一打开就可以看到.难的是要通过代码明白作者当初为什么要这样设计,设计之初要解决的主要问 ...

  4. 【CEDEC 2015】【夏日课堂】制作事宜技术篇,新手职员挑战VR Demo开发的真相

    日文原文地址 http://www.4gamer.net/games/277/G027751/20150829002/ PS:CEDEC 2015的PPT有些要到10月才有下载,目前的都是记者照片修图 ...

  5. javascript Array类

    Array类 toString()方法和valueOf()方法,返回特殊的字符串.该字符串是通过对每项调用toString()方法,然后用逗号把它们连接在一起构成的.例如,对具有项"red& ...

  6. 推荐的PHP编码规范

    推荐的PHP编码规范 发布时间: 2014-05-7 浏览次数:2754 分类: PHP教程 推荐的PHP编码规范 一 编辑器设置 1. 使用Tab缩进,不要使用空格 鉴于很多编辑器在保存文件时会自动 ...

  7. Rails--default_scope

    Example: default_scope where("agents.deleted = ?", false)

  8. 使用fsck修复文件系统错误

    1.问题描述 服务器maint_samba   由于服务器maint_samba (debian操作系统)没有正常关机,在重新启动过程中/dev/sdb1出现文件系统错误,需要手动使用fsck进行扫描 ...

  9. 学习之道-从求和起-求和曲线面积瞬时速率极限微积分---求和由高解低已知到未知高阶到低阶连续自然数的K次方之和

    数学分析 张筑生

  10. Jquery小例子:全选按钮、加事件、挂事件;parent()语法;slideToggle()语法;animate()语法;元素的淡入淡出效果:fadeIn() 、fadeOut()、fadeToggle() 、fadeTo();function(e):e包括事件源和时间数据;append() 方法

    function(e): 事件包括事件源和事件数据,事件源是指是谁触发的这个事件,谁就是事件源(div,按钮,span都可以是事件源),时间数据是指比如点击鼠标的事件中,事件数据就是指点击鼠标的左建或 ...