参考文献:

细说SQL Server中的加密

Transparent Data Encryption (TDE)

Database Encryption Key (DEK) management

SQL Server中的加密简介

  在SQL Server2000和以前的版本,是不支持加密的。所有的加密操作都需要在程序中完成。这导致一个问题,数据库中加密的数据仅仅是对某一特定程序有意义,而另外的程序如果没有对应的解密算法,则数据变得毫无意义。举个例子来说,我以前写过一个web应用程序(参考博客:自定义SqlMembershipProvider方法),想让用户信息中的密码字段用密文保存,我是在程序中将用户的明文密码加密以后保存到数据库中的。

  到了SQL Server2005,引入了列级加密。使得加密可以对特定列执行,这个过程涉及4对加密和解密的内置函数。

  SQL Server 2008时代,则引入的了透明数据加密(TDE),所谓的透明数据加密,就是加密在数据库中进行,但从程序的角度来看就好像没有加密一样,和列级加密不同的是,TDE加密的级别是整个数据库。使用TDE加密的数据库文件或备份在另一个没有证书的实例上是不能附加或恢复的。

对称加密与非对称加密

  通常来说,加密可以分为两大类,对称(Symmetric)加密和非对称(Asymmetric)加密。

  对称加密是那些加密和解密使用同一个密钥的加密算法,就是加密密钥=解密密钥。对称加密通常来说会比较羸弱,因为使用数据时不仅仅需要传输数据本身,还是要通过某种方式传输密钥,这很有可能使得密钥在传输的过程中被窃取。

  非对称加密是那些加密和解密使用不同密钥的加密算法,就是加密密钥!=解密密钥。用于加密的密钥称之为公钥,用于解密的密钥称之为私钥。因此安全性相比对称加密来说会大大提高。当然有一长必有一短,非对称加密的方式通常算法会相比对称密钥来说复杂许多,因此会带来性能上的损失。

  因此,一种折中的办法是使用对称密钥来加密数据,而使用非对称密钥来加密对称密钥。这样既可以利用对称密钥的高性能,还可以利用非对称密钥的可靠性。

证书与密钥的创建

每个数据库有且只有一个数据库主密钥(master key),这是一个数据库级别的密钥。可以用于为创建数据库级别的证书或非对称密钥提供加密。通过T-SQL语句创建,如代码1所示。

--创建证书,对称与非对称密钥需要master key
--创建master key
CREATE MASTER KEY ENCRYPTION BY PASSWORD ='P@ssw0rd'; --删除master key
drop MASTER KEY ;

如果要查看数据库是否有master key,可以通过下面的T-SQL语句查询

--在SSMS中没有查看master key的地方,但是可以在sys.databases中查看到数据库是否有master key
select name,is_master_key_encrypted_by_server from sys.databases

我的查询结果如下图所示:

从上图中我们可以看到master和TESTDB4这两个数据库含有master key,而且数据库没有。所以说master并不是只在master数据库下面的,如果我们要在TESTDB4中创建证书与密钥,那么就必须为TESTDB4这个数据库创建master key。

下面给出创建证书、对称密钥、非对称密钥的T-SQL代码

use TESTDB3;

--创建证书
CREATE CERTIFICATE CertTest
with SUBJECT = 'Test Certificate'
GO --创建非对称密钥
CREATE ASYMMETRIC KEY TestAsymmetric
WITH ALGORITHM = RSA_2048
ENCRYPTION BY PASSWORD = 'P@ssw0rd';
GO --创建对称密钥
CREATE SYMMETRIC KEY TestSymmetric
WITH ALGORITHM = AES_256
ENCRYPTION BY PASSWORD = 'P@ssw0rd';
GO

创建完以后我们可以在SSMS中找到我们创建的证书与密钥,如下图所示:

上面创建的证书、对称密钥、非对称密钥都是由固定的对称密钥P@ssw0rd加密的。其实创建的证书、对称密钥、非对称密钥的时候,也可以使用证书、对称密钥、非对称密钥加密,T-SQL代码如下:

--由证书加密对称密钥
CREATE SYMMETRIC KEY SymmetricByCert
WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE CertTest;
GO --由对称密钥加密对称密钥
OPEN SYMMETRIC KEY TestSymmetric
DECRYPTION BY PASSWORD='P@ssw0rd'
--必须先open 了TestSymmetric以后才可以用TestSymmetric来加密
CREATE SYMMETRIC KEY SymmetricBySy
WITH ALGORITHM = AES_256
ENCRYPTION BY SYMMETRIC KEY TestSymmetric;
GO --由非对称密钥加密对称密钥
CREATE SYMMETRIC KEY SymmetricByAsy
WITH ALGORITHM = AES_256
ENCRYPTION BY ASYMMETRIC KEY TestASymmetric;
GO

创建完以后我们在Symmetric Key中可以看到我们查询的结果:

列级加密

  在列级加密中我们将使用AdventureWorks2008R2这个样例数据库,在Sales.CreditCard这张表中我们可以看到CardNumber列是明文的,如下图所示:

在实际生产环境中,如果用户的信用卡号是明文的是非常不安全的, 我们在这项想将这个CardNumber使用列级加密。需要注意的是,进行加密或者解密的列必须是Varbinary类型。

首先我们创建不带数据的CreditCard的表结构,并且CardNumber这个列是Varbinary类型,T-SQL代码如下:

--创建不带数据的表结构,有where 1<>1来控制
SELECT CreditCardID,
CardType,
CardNumber_encrypt = CONVERT(varbinary(500), CardNumber),
ExpMonth,
ExpYear,
ModifiedDate
INTO CreditCard_Encrypt
FROM AdventureWorks2008R2.Sales.CreditCard
WHERE 1<>1

在创建表结构以后,我们将数据导入到这张表中去:

--打开之前创建的由证书加密的对称密钥
OPEN SYMMETRIC KEY SymmetricByCert DECRYPTION BY CERTIFICATE CertTest; --利用这个密钥加密CardNumber这个数据列,插入新建的表中,使用了EncryptByKey这个函数
insert CreditCard_encrypt (
CardType,
CardNumber_encrypt,
ExpMonth,
ExpYear,
ModifiedDate
)
select top 10
CardType,
CardNumber_encrypt = EncryptByKey(KEY_GUID('SymmetricByCert'), CardNumber),
ExpMonth,
ExpYear,
ModifiedDate
from AdventureWorks2008R2.Sales.CreditCard

查询CreditCard_encrypt这个表,我们可以发现CardNumber列是密文了,如下图所示:

但是我们可以通过对称密钥来解密CardNumber这个列

--打开之前创建的由证书加密的对称密钥
OPEN SYMMETRIC KEY SymmetricByCert DECRYPTION BY CERTIFICATE CertTest;
--查看CardNumber_encrypt
select convert(nvarchar(25), DecryptByKey(CardNumber_encrypt)) from CreditCard_Encrypt;

使用这条语句查询出来的结果就是CardNuber的明文了。 注意这里需要OPEN SYMMETRIC KEY,如果不打开这个对称私钥的话查询结果是null。如果之前打开过这个私钥,那么此处可以不用再次打开。

透明数据加密

  在SQL Server 2008中引入了透明数据加密(Transparent Data Encryption ,以下简称TDE),之所以叫透明数据加密,是因为这种加密在使用数据库的程序或用户看来,就好像没有加密一样。TDE加密是数据库级别的。数据的加密和解密是以页为单位,由数据引擎执行的。在写入时进行加密,在读出时进行解密。客户端程序完全不用做任何操作。(Encryption of the database file is performed at the page level. The pages in an encrypted database are encrypted before they are written to disk and decrypted when read into memory. TDE does not increase the size of the encrypted database.)

  TDE的主要作用是防止数据库备份或数据文件被偷了以后,偷数据库备份或文件的人在没有数据加密密钥的情况下是无法恢复或附加数据库的。我将一个encrypted database拷贝到另外的一台服务器上,视图attach这个database,但是报错如下:

上述错误表明这台服务器没有相应的证书。这从另一个角度也给我们做了提醒,如果是一个encrypted database的话, 我不单要备份数据库,还要对证书做备份,如果我们自身证书丢失的话,也会开不开数据库。

  TDE使用数据加密密钥(DEK)进行加密。DEK是存在Master数据库中由服务主密钥保护,由的保护层级如下图所示。

使用TDE的四个步骤为:

  1. 创建一个master key(Create a master key)

    USE master;
    GO --在master数据库中创建一个master key
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'P@ssw0rd';
    go
  2. 创建或者获取一个由master key保护的证书(Create or obtain a certificate protected by the master key)

    --使用masterkey创建证书MyServerCert
    CREATE CERTIFICATE MyServerCert WITH SUBJECT = 'My DEK Certificate';
    go
  3. 使用证书创建一个database密钥(Create a database encryption key and protect it by the certificate)

    1. 但是在创建完DATABASE ENCRYPTION KEY(DEK)以后,会报如下警告:

      USE TESTDB2;
      GO --创建数据库加密key,使用MyServerCert这个证书加密
      CREATE DATABASE ENCRYPTION KEY
      WITH ALGORITHM = AES_128
      ENCRYPTION BY SERVER CERTIFICATE MyServerCert;
      GO

      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.

      这是因为我们使用了证书来创建DEK,并且加密数据库,因此我们建议为证书做一个备份,否则如果证书被破坏以后,我们自身都无法打开数据库。证书备份的方法可以参考:backup certificate,我的T-SQL所示:

      BACKUP CERTIFICATE MyServerCert TO FILE = 'd:\storedcerts\MyServerCert'; --cert的保存地址 

      这里需要注意的是我们的MyServerCert没有由private key加密,而只是有master key加密。如果使用了private key的话还要为private key进行备份。我们如果对MyServerCert进行备份private key操作会报错如下:

      No decryption password should be provided because the private key of this certificate is encrypted by a master key.

  4. 将数据库设置为TDE(Set the database to use encryption)

       最后我们需要做的就是讲数据库设置为加密,T-SQL语句如下所示:

ALTER DATABASE TESTDB2 SET ENCRYPTION ON;

       此时我们也可以右键TESTDB2->tasks->manage database encryption中查看加密设置,如下图所示:

我们也可以通过T-SQL语句来查看有哪些数据库进行了TDE加密,T-SQL语句如下:

/* The value 3 represents an encrypted state
on the database and transaction logs. */
SELECT DBName=DB_NAME(database_id),encryption_state
FROM sys.dm_database_encryption_keys
WHERE encryption_state = 3;
GO

查询结果显示tempdb也被透明加密了,原因我们可以在msdn上找到,我把原文摘出来:

Transparent Data Encryption and the tempdb System Database

The tempdb system database will be encrypted if any other database on the instance of SQL Server is encrypted by using TDE. This might have a performance effect for unencrypted databases on the same instance of SQL Server. For more information about the tempdb system database, see tempdb Database.

master key和certificate的备份与还原

--备份master key
BACKUP MASTER KEY TO FILE = 'd:\storedkeys\masterkey' ENCRYPTION BY PASSWORD = 'P@ssw0rd'
go --备份证书
BACKUP CERTIFICATE MyServerCert TO FILE = 'd:\storedcerts\MyServerCert'; --cert的保存地址
go --还原master key
use master
RESTORE MASTER KEY
FROM FILE = 'd:\storedkeys\masterkey'
DECRYPTION BY PASSWORD = 'P@ssw0rd'
ENCRYPTION BY PASSWORD = 'P@ssw0rd';
GO
--因为我这里还留有原来的证书,所以会提示如下信息:The old and new master keys are identical. No data re-encryption is required. --还原证书
CREATE CERTIFICATE MyServerCert2
FROM FILE = 'd:\storedcerts\MyServerCert'
GO
--因为证书已经存在,所以提示如下信息:--A certificate with name 'MyServerCert2' already exists or this certificate already has been added to the database.
--需要注意的是证书并不是按照证书名来区分的。我原来的证书名叫做MyServerCert,此处创建的证书名为MyServerCert2,但是是来自MyServerCert的一个备份,还是报错。

SQL Server中的加密的更多相关文章

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

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

  2. 细说SQL Server中的加密【转】

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

  3. 细说SQL Server中的加密

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

  4. (4.23)SQL Server中的加密

    转自:https://www.cnblogs.com/CareySon/archive/2012/04/01/SQL-SERVER-Encryption.html 简介 加密是指通过使用密钥或密码对数 ...

  5. c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

  6. 在SQL SERVER中实现RSA加解密函数(第二版)

    /*************************************************** 作者:herowang(让你望见影子的墙) 日期:2010.1.5 注: 转载请保留此信息 更 ...

  7. 在SQL SERVER中实现RSA加解密函数(第一版)

    /*************************************************** 作者:herowang(让你望见影子的墙) 日期:2010.1.1 注:   转载请保留此信息 ...

  8. 理解SQL Server中的权限体系(上)----主体

    原文:http://www.cnblogs.com/CareySon/archive/2012/04/10/mssql-security-principal.html 简介 权限两个字,一个权力,一个 ...

  9. Sql Server数据的加密与解密

    Sql Server数据的加密与解密 在sql server中,我们如何为数据进行加密与解密,避免使用者窃取机密数据? 对于一些敏感数据,如密码.卡号,一般不能使用正常数值来存储.否则会有安全隐患.以 ...

随机推荐

  1. vue 传入一个对象的所有属性

  2. mysql双主模式方案

    MySQL双主(主主)架构方案   在企业中,数据库高可用一直是企业的重中之重,中小企业很多都是使用mysql主从方案,一主多从,读写分离等,但是单主存在单点故障,从库切换成主库需要作改动.因此,如果 ...

  3. vue router.beforeEach(),详解

    outer.beforeEach()一般用来做一些进入页面的限制. 比如没有登录, 就不能进入某些页面,只有登录了之后才有权限查看某些页面...说白了就是路由拦截.第一步 规定进入路由需不需要权限 @ ...

  4. 入门指引之查看accesstoken

    1. 测试工具查看 https://mp.weixin.qq.com/debug/ 2. 代码获取: # -*- coding: utf-8 -*- # filename: basic.py impo ...

  5. yum -y install 问题解决

    1.错误如下: Last login: Thu Jul 26 09:04:14 2018 from 192.168.3.250[root@diagbot01 ~]# yum -y install do ...

  6. 42 | grant之后要跟着flush privileges吗?

    在 MySQL 里面,grant 语句是用来给用户赋权的.不知道你有没有见过一些操作文档里面提到,grant 之后要马上跟着执行一个 flush privileges 命令,才能使赋权语句生效.我最开 ...

  7. oom killer 详解

    一.oom killer理解和日志分析:知识储备 oom killer日志分析,这是前篇,准备一些基础知识 带着问题看: 1.什么是oom killer 是Linux内核设计的一种机制,在内存不足的时 ...

  8. MySQL 语句整理 2019-5-3

    MySQL 语句整理 在整理完Oracle的一些常见用语句后,由于MySQL的语法跟Oracle略有不同,随跟PN的MySQL视频进行了间接整理. 查询薪水大于1800, 并且部门编号为20或30的员 ...

  9. Oracle Linux 6.4 LVM中误删VG之恢复过程

    一.项目背景描述 1.OSS现网测试数据库因大量小事物频繁提交运行非常缓慢.经分析为DS3950存储所在磁盘I/O存在瓶颈,大量等待事件,性能受限.另外,开发同事没有优化意识,没将小事物做成批量提交方 ...

  10. 好久木来了,一直忙于项目(加懒惰),今天讲讲vuecli3.0的使用

    vue更新换代很快,马上vue都要出3.0了,这是一个巨大的变革,不过今天讲的是vuecli3.0,里面使用的vue仍然是2的,所有可以放心大胆使用. Vue CLI 是一个基于 Vue.js 进行快 ...