您的位置:首页 > 数据库

SQL Server 安全篇——SQL Server加密(2)——加密数据

2018-02-26 14:04 232 查看

本文属于SQL Server安全专题系列

    在SQL SERVER中的数据可以使用密码或者证书来加密。本文分别来演示一下使用密码和证书来加密。

使用密码或短语(passphrase)加密数据

    在SQL Server中最常见的数据加密函数是ENCRYPTBPASSPHRASE()。这个函数可以使用密码或者短语直接对数据加密而不需要经过SQL Server的加密层次体系。下面使用AdventureWorks2016的Sales.CreditCard表进行演示。从名字可以看出这个表是存储信用卡信息。如果打开表,可以看到还是明文存储,这种安全性明显是不足的。注意:如果读者根据前面章节实操下来,会发现在SQL Server 安全篇——安全元数据(4)——加密(Ecryption)元数据中对这个表的数据进行了AE(Always Encrypted),这里要先去掉:


或使用脚本:USE AdventureWorks2016
GO
ALTER TABLE Sales.CreditCard
ALTER COLUMN CardNumber DROP MASKED ; 下面查看原文可以发现如下图的内容:


要加密这个列,需要进行以下步骤:

创建一个varbinary类型的新列
加密CardNumber列并插入数据到新列。
Drop掉原列(CardNumber)
更新代码让其使用新的列。

Step 1:创建新列

首先,注意数据类型为varbinary,其次,由于一开始并没有值,也没有默认值,所以在加列时注意不要使用NOT NULL。USE AdventureWorks2016
GO
ALTER TABLE Sales.CreditCard ADD
CardNumberEncrypted varbinary(8000) NULL ;


Step 2:加密并插入数据

    实际上就是更新CardNumberEncrypted列,数据来源为CardNumber。使用ENCRYPTBYPASSPHRASE()函数加密CardNumber的值,第三个参数为:add_authenticator,指示是否将验证器与明文一起加密。 如果将添加验证器,则为 1。 这里不添加,所以为0。 UPDATE Sales.CreditCard
SET CardNumberEncrypted = ENCRYPTBYPASSPHRASE('Pa$$w0rd', CardNumber, 0) ;

SELECT TOP 1 * FROM Sales.CreditCard


    接下来可以对CardNumberEncrypted修改NOT NULL配置。然后删除原列。

Step 3:删除原列

    注意如果后续要使用这列,则不要执行,本文先备份数据库之后再执行,测试完之后还原数据库。--修改新列的NOT NULL配置。
ALTER TABLE Sales.CreditCard
ALTER COLUMN CardNumberEncrypted VARBINARY(256) NOT NULL ;

--备份数据库之后才执行下面语句
DROP INDEX AK_CreditCard_CardNumber ON Sales.CreditCard ;
GO
ALTER TABLE Sales.CreditCard
DROP COLUMN CardNumber ;

SELECT TOP 1 * FROM Sales.CreditCard

Step 4:修改代码使用新列

    由于原列已经被Drop,为了不影响相关代码的运行,需要修改所有依赖代码,这个是非常大的工作量,所以在决定是否加密前,要做好检查和评估。
    假设原代码(这里是存储过程)如下:
CREATE PROCEDURE ReturnCredCardInfo @BusinessEntityID INT
AS
BEGIN
SELECT p.BusinessEntityID
,p.firstName
,p.LastName
,cc.CardNumber
,cc.CardType
,cc.ExpMonth
,cc.ExpYear
FROM Person.Person p
INNER JOIN Sales.PersonCreditCard pcc ON p.BusinessEntityID = pcc.BusinessEntityID
INNER JOIN Sales.CreditCard cc ON pcc.CreditCardID = cc.CreditCardID
WHERE p.BusinessEntityID = @BusinessEntityID;
END
    修改源代码并非简单地把列名修改即可,因为如上面演示中,新列是已经加密的数据,直接查出来并没有什么意义,需要进行解密,使用  DECRYPTBYPASSPHRASE()函数。ALTER PROCEDURE ReturnCredCardInfo @BusinessEntityID INT
AS
BEGIN
SELECT p.BusinessEntityID
,p.firstName
,p.LastName
,CONVERT(NVARCHAR(25), DECRYPTBYPASSPHRASE('Pa$$w0rd', cc.CardNumberEncrypted, 0)) as CardNumber
,cc.CardType
,cc.ExpMonth
,cc.ExpYear
FROM Person.Person p
INNER JOIN Sales.PersonCreditCard pcc ON p.BusinessEntityID = pcc.BusinessEntityID
INNER JOIN Sales.CreditCard cc ON pcc.CreditCardID = cc.CreditCardID
WHERE p.BusinessEntityID = @BusinessEntityID;
END


 

使用密钥和证书加/解密

    密钥和证书加密属于SQL Server的加密层次体系,可以使用对称密钥、非对称密钥或者证书来加密。下表是加密类型及其使用函数:

加密类型加密函数解密函数
对称加密ENCRYPTBYKEY()DECRYPTBYKEY()
非对称加密

ENCRYPTBYASYMKEY ()

DECRYPTBYASYMKEY()
证书ENCRYPTBYCERT()DECRYPTBYCERT()
    三种方式中,从性能方面考虑,使用对称密钥性能最好。下面来演示一下使用对称密钥加密数据,首先需要创建一个证书,然后才能创建对称密钥。最后使用密钥对前面演示的CardNumberEncrypted列进行加密。
    首先先还原一下数据库,然后创建库的master key,因为备份是原始的,如果读者备份时已经创建了master key,则可以不执行这一步:
USE AdventureWorks2016
GO
--创建数据库主密钥,使用密码加密
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Pa$$w0rd' ;

加密数据:

Step 1:创建证书

    对于证书,可以使用CREATE CERTIFICATE命令创建,也可以用这个命令的导入功能导入已存在的证书。USE AdventureWorks2016
GO
--创建证书
CREATE CERTIFICATE CreditCardCert --证书名
WITH SUBJECT = 'Credit Card Numbers'; --证书主题
GO

Step 2:创建对称密钥

    使用CREATE SYMMETRIC KEY命令创建对称密钥。可以同时使用多个证书、密码、对称密钥及非对称密钥对单个对称密钥进行加密。--创建对称密钥
CREATE SYMMETRIC KEY CreditCardKey
WITH ALGORITHM = AES_128 --使用AES_128算法加密
ENCRYPTION BY CERTIFICATE CreditCardCert; --使用证书加密,这里可以指定使用密码、对称密钥和非对称密钥加密    从 SQL Server 2016开始,除 AES_128、AES_192 和 AES_256 以外的所有算法都已过时。 若要使用较旧算法 (不推荐),必须设置数据库到数据库兼容性级别 120 或更低。

Step 3:解密对称密钥并使其可供使用

    注意打开操作是绑定到会话而不是上下文。在显式关闭会话或者会话终止前一直有效。--使用密钥前需要解密对称密钥然后打开密钥,否则密钥不可用
OPEN SYMMETRIC KEY CreditCardKey DECRYPTION BY CERTIFICATE CreditCardCert;

Step 4:使用密钥对数据进行加密(即更新操作)

    由于前面演示中已经drop掉加密列,所以先添加:USE AdventureWorks2016
GO
ALTER TABLE Sales.CreditCard ADD
CardNumberEncrypted varbinary(8000) NULL ;     然后进行加密:
--使用对称密钥对数据进行加密(更新操作)
UPDATE Sales.CreditCard
SET CardNumberEncrypted = ENCRYPTBYKEY(Key_GUID('CreditCardKey'), CardNumber);


Step 5:关闭密钥

--关闭密钥
CLOSE SYMMETRIC KEY CreditCardKey ;


数据解密

    数据加密以后,同样,使用时需要解密,那么对应的解密函数就是  DECRYPTBYKEY()。下面演示一下,注意同样需要打开和关闭密钥:USE AdventureWorks2016
GO
--打开密钥
OPEN SYMMETRIC KEY CreditCardKey DECRYPTION BY CERTIFICATE CreditCardCert;

--使用对称密钥解密数据
SELECT CONVERT(NVARCHAR(30), DECRYPTBYKEY(CardNumberEncrypted)) AS CreditCardNumber
FROM Sales.CreditCard ;

--关闭密钥 CLOSE SYMMETRIC KEY CreditCardKey ;

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  SQL Server DBA 安全 加密