当前位置: 代码迷 >> SQL >> SQLServer 数据加密解密(1)
  详细解决方案

SQLServer 数据加密解密(1)

热度:25   发布时间:2016-05-05 10:39:23.0
SQLServer 数据加密解密(一)

都是基本示例,更多参考官方文档:

1. Transact-SQL 函数
2. 数据库密钥
3. 证书
4. 非对称密钥
5. 对称密钥


--	drop table EnryptTestcreate table EnryptTest(	id int not null primary key,	EnryptData nvarchar(20),)insert into EnryptTestvalues(1,N'888888'),(2,N'888888'),(3,N'123456'),(4,N'A');select * from EnryptTest;

【Transact-SQL 函数加密】

/***********************************【Transact-SQL 函数加密】********************************/--	使用 TRIPLE DES 算法(128 密钥位长度)的通行短语加密数据。--	添加测试列alter table EnryptTest add PassPhrase varbinary(256)alter table EnryptTest add PassPhrase2 varbinary(256)--用于验证器验证--	加密(EncryptByPassPhrase)--	https://technet.microsoft.com/zh-cn/library/ms190357%28v=sql.105%29.aspx?f=255&MSPPError=-2147217396update EnryptTest set PassPhrase = EncryptByPassPhrase('Hello.kk',EnryptData)goupdate EnryptTest set PassPhrase2 = EncryptByPassPhrase	(	  'Hello.kk'			--用于生成对称密钥的通行短语	, EnryptData			--要加密的明文	, 1						--指示是否将验证器与明文一起加密。如果将添加验证器,则为 1	, convert(varbinary,id)	--用于派生验证器的数据(如 主键)	)go--	解密(DecryptByPassPhrase)--	https://technet.microsoft.com/zh-cn/library/ms188910%28v=sql.105%29.aspx?f=255&MSPPError=-2147217396select convert(nvarchar,DecryptByPassphrase('Hello.kk',PassPhrase)) from EnryptTest;goselect convert(nvarchar,DecryptByPassphrase(	  'Hello.kk'	--生成解密密钥的通行短语	, PassPhrase2	--要解密的加密文本varbinary 	, 1				--添加验证器	, convert(varbinary,id)))--验证器为主键from EnryptTest;go--附:未用验证器的,数据并不安全--如:把所有id的密码都改为与A一样,其他密码的解密与A一样,别人就有可能登录其他账号update EnryptTest set PassPhrase = (select PassPhrase from EnryptTest where id=4)goselect id,EnryptData,convert(nvarchar,DecryptByPassphrase('Hello.kk',PassPhrase)) from EnryptTest;--	删除测试列alter table EnryptTest drop column PassPhrase alter table EnryptTest drop column PassPhrase2go

【数据库主密钥】

/***************************************【数据库主密钥】***********************************/select * from sys.key_encryptionsselect * from sys.crypt_properties--	创建数据库主密钥--	https://technet.microsoft.com/zh-cn/library/ms174382(v=sql.105).aspxcreate master key encryption by password = N'[email protected]' --必须符合Windows密码策略要求go--	打开当前数据库的数据库主密钥--	https://technet.microsoft.com/zh-cn/library/ms186336(v=sql.105).aspxopen master key decryption by password = N'[email protected]'go--	更改数据库主密钥的属性--	https://technet.microsoft.com/zh-cn/library/ms186937(v=sql.105).aspxalter master key regenerate with encryption by password = N'[email protected]'alter master key add encryption by password = N'[email protected]'alter master key drop encryption by password = N'[email protected]'alter master key add encryption by service master keyalter master key drop encryption by service master key--	导出数据库主密钥--	https://technet.microsoft.com/zh-cn/library/ms174387(v=sql.105).aspxbackup master key to file = N'D:\XXDB_MasterKey' encryption by password = N'[email protected]'go--	从备份文件中导入数据库主密钥--	https://technet.microsoft.com/zh-cn/library/ms186336(v=sql.105).aspxrestore master key 	from file = N'D:\XXDB_MasterKey'    decryption by password = N'[email protected]'    encryption by password = N'[email protected]' --New Passwordgo--	从当前数据库中删除主密钥--	https://technet.microsoft.com/zh-cn/library/ms180071(v=sql.105).aspxdrop master keygo

【证书】

/*****************************************【证书】*************************************/--	证书和非对称密钥使用数据库级的内部公钥加密数据,并且使用数据库级内部私钥解密数据--	当使用数据库主密钥对私钥进行加密时,不需要 ENCRYPTION BY PASSWORD 选项。私钥使用数据库主密钥进行加密--(有点难理解,最后给出例子)select * from sys.key_encryptionsselect * from sys.crypt_propertiesselect * from sys.certificatesselect * from EnryptTest--	添加测试列alter table EnryptTest add CertificateCol varbinary(max)go--	创建证书--	https://technet.microsoft.com/zh-cn/library/ms187798%28v=sql.105%29.aspx?f=255&MSPPError=-2147217396create certificate Mycertificateencryption by password = N'[email protected]'	--加密密码with subject = N'EnryptData certificate',		--证书描述  start_date = N'20150401',	--证书生效日 expiry_date = N'20160401';	--证书到期日  go--	使用证书的公钥加密数据--	https://msdn.microsoft.com/zh-cn/library/ms188061(v=sql.105).aspxupdate EnryptTest set CertificateCol = EncryptByCert(CERT_ID('Mycertificate'),CONVERT(VARCHAR(MAX),EnryptData))go--	用证书的私钥解密数据--	https://msdn.microsoft.com/zh-cn/library/ms178601(v=sql.105).aspxselect *,CONVERT(VARCHAR(MAX ),DECRYPTBYCERT(CERT_ID('Mycertificate'),CertificateCol,N'[email protected]'))from EnryptTest;go--	修改私钥密码 --	https://msdn.microsoft.com/zh-cn/library/ms189511(v=sql.105).aspxalter certificate mycertificate with private key (	decryption by password = N'[email protected]', 	encryption by password = N'[email protected]')go--	从证书中删除私钥 alter certificate mycertificate remove private keygo--	备份证书--	https://msdn.microsoft.com/zh-cn/library/ms178578(v=sql.105).aspxbackup certificate mycertificate to file = N'D:\mycertificate.cer' --用于加密的证书备份路径with private key ( 	file = N'D:\mycertificate_saleskey.pvk' , --用于解密证书私钥文件路径 	decryption by password = N'[email protected]' ,--对私钥进行解密的密码	encryption by password = N'[email protected]' );--对私钥进行加密的密码go--	创建/还原证书create certificate mycertificate from file = N'D:\mycertificate.cer' with private key (    file = N'D:\mycertificate_saleskey.pvk',     decryption by password = '[email protected]');go--	删除对称密钥--	https://msdn.microsoft.com/zh-cn/library/ms182698(v=sql.105).aspxdrop certificate  Mycertificate;go--	删除测试列alter table EnryptTest drop column CertificateCol;go

【非对称密钥】

/***************************************【非对称密钥】*************************************/--	默认情况下,私钥受数据库主密钥保护select * from sys.key_encryptionsselect * from sys.crypt_propertiesselect * from sys.certificatesselect * from sys.asymmetric_keysselect * from sys.openkeysselect * from EnryptTest--	添加测试列alter table EnryptTest add AsymmetricCol varbinary(max)go--	创建非对称密钥--	https://msdn.microsoft.com/zh-cn/library/ms174430(v=sql.105).aspxcreate asymmetric key MyAsymmetric with 	algorithm=rsa_512 	encryption by password='[email protected]';go  --	加密(EncryptByAsymKey)--	https://msdn.microsoft.com/ZH-CN/library/ms186950(v=sql.105).aspxupdate EnryptTest set AsymmetricCol = EncryptByAsymKey(asymkey_id ('MyAsymmetric'),convert(varchar(max ),EnryptData))  go--	解密(DecryptByAsymKey)--	https://msdn.microsoft.com/ZH-CN/library/ms189507(v=sql.105).aspxselect *,convert(varchar(max),DecryptByAsymKey(asymkey_id('MyAsymmetric'),AsymmetricCol,N'[email protected]'))from EnryptTestgo--	更改非对称密钥属性--	https://msdn.microsoft.com/zh-cn/library/ms187311(v=sql.105).aspx--	更改私钥密码alter asymmetric key MyAsymmetric     with private key (    decryption by password = N'[email protected]',--原私钥密码    encryption by password = N'[email protected]');--新私钥密码go--	删除私钥,只保留公钥--	如果将非对称密钥映射到 EKM 设备上的可扩展密钥管理 (EKM) 密钥并且未指定 REMOVE PROVIDER KEY 选项,--	则会从数据库中删除该密钥,但不会从设备上删除它。这时会发出一条警告。alter asymmetric key MyAsymmetric remove private key;go--	删除非对称密钥--	https://msdn.microsoft.com/ZH-CN/library/ms188389(v=sql.105).aspxdrop symmetric key MyAsymmetric ;go--	删除测试列alter table EnryptTest drop column AsymmetricColgo

【对称密钥】

/***************************************【对称密钥】*************************************/--	也称为单密钥加密,采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密.--	非对称密钥消耗多些系统性能,一般使用对称密钥加密数据,使用非对称密钥保护对称密钥select * from sys.key_encryptionsselect * from sys.crypt_propertiesselect * from sys.certificatesselect * from sys.asymmetric_keysselect * from sys.openkeysselect * from sys.symmetric_keysselect * from EnryptTest--	添加测试列alter table EnryptTest add SymmetricCol varbinary(max)go--	创建对称密钥--	https://msdn.microsoft.com/zh-cn/library/ms188357(v=sql.105).aspxcreate symmetric key MySymmetric	--以密码加密的对称密钥with 	algorithm=aes_128 	encryption by password='[email protected]';gocreate symmetric key MySymmetric	--以非对称密钥加密的对称密钥with 	algorithm=aes_128 	encryption by asymmetric key MyAsymmetricgo--	打开对称密钥(打开才能有效使用加密解密函数)--	https://msdn.microsoft.com/zh-cn/library/ms190499(v=sql.105).aspxopen symmetric key MySymmetric decryption by password='[email protected]';goopen symmetric key MySymmetric decryption by asymmetric key MyAsymmetric with password='[email protected]';go--	加密数据--	https://technet.microsoft.com/zh-cn/library/ms174361%28v=sql.105%29.aspx?f=255&MSPPError=-2147217396update EnryptTest set SymmetricCol = encryptbykey(key_guid('MySymmetric'),convert(varchar(max),EnryptData))go--	解密数据--	https://technet.microsoft.com/zh-cn/library/ms181860(v=sql.105).aspxselect *,convert(varchar(max ) ,convert (varchar(max ),decryptbykey(SymmetricCol)))  from EnryptTestgo--	关闭对称密钥,或关闭在当前会话中打开的所有对称密钥--	https://msdn.microsoft.com/zh-cn/library/ms177938%28v=sql.105%29.aspx?f=255&MSPPError=-2147217396--	close all symmetric keys; close symmetric key MySymmetric;go--	alter symmetric 添加或删除新的加密方式(如添加多多个密码,任何一个密码都可用)--	https://msdn.microsoft.com/zh-cn/library/ms189440(v=sql.105).aspxopen symmetric key MySymmetric decryption by password='[email protected]';alter symmetric key MySymmetric add encryption by password = '[email protected]' --New another Passwordclose symmetric key MySymmetric;open symmetric key MySymmetric decryption by password='[email protected]'; --Use New Passwordselect convert(varchar(max ) ,convert (varchar(max ),decryptbykey(SymmetricCol))) from EnryptTestalter symmetric key MySymmetric drop encryption by password = '[email protected]'--Drop the new Passwordclose symmetric key MySymmetric;go--	删除对称密钥--	https://msdn.microsoft.com/zh-cn/library/ms182698(v=sql.105).aspxdrop symmetric key MySymmetric;go--	删除测试列alter table EnryptTest drop column SymmetricColgo

【示例】

--	测试数据/*drop certificate  Mycertificate;godrop master keygodrop table EnryptTestgo*/create table EnryptTest(	id int not null primary key,	EnryptData nvarchar(20),)goinsert into EnryptTestvalues(1,N'888888'),(2,N'888888'),(3,N'123456'),(4,N'A');goselect * from EnryptTest;alter table EnryptTest add CertificateCol varbinary(max)go--创建主密钥create master key encryption by password = N'[email protected]'go/*key_id	thumbprint	crypt_type	crypt_type_desc				crypt_property------	----------	----------	---------------------	------------------101		0x01		ESKM		ENCRYPTION BY MASTER KEY	0x7A2FEDA8139F1DE8F3377424C120DBDB8E1F7EAAEC1BBD73E72AC04F5CEECBFAC15FC7E130CA1756281EA0D8E6997F44101		NULL		ESKP		ENCRYPTION BY PASSWORD		0x61D8F28F12CE4A1247F91E0ED828F2E937206E5D69B0754EE76756567AB428CBD5B54B76BCD1FC15E5E12202DBA4E187*/--创建证书,因为默认使用主密钥加密,此处不需要密码create certificate Mycertificatewith subject = N'EnryptData certificate',start_date = N'20150401',expiry_date = N'20160401';go--加密解密都自动使用服务主密钥加密了。即使使用“close master key ”也不起作用update EnryptTest set CertificateCol = EncryptByCert(CERT_ID('Mycertificate'),CONVERT(VARCHAR(MAX),EnryptData))goselect *,CONVERT(VARCHAR(MAX ),DECRYPTBYCERT(CERT_ID('Mycertificate'),CertificateCol)) from EnryptTest;go--现在删除“服务主密钥”alter master key drop encryption by service master keygo--再查询数据,没有解密出来。不自动使用主密钥加密解密了select *,CONVERT(VARCHAR(MAX ),DECRYPTBYCERT(CERT_ID('Mycertificate'),CertificateCol)) from EnryptTest;go--这时需要显式打开主密钥,使用主密钥密码加密解密open master key decryption by password = N'[email protected]'go--再查询数据,解密出来了。select *,CONVERT(VARCHAR(MAX ),DECRYPTBYCERT(CERT_ID('Mycertificate'),CertificateCol)) from EnryptTest;go--最后关闭主密钥close master key go--查看主密钥,少了"ENCRYPTION BY MASTER KEY",没有了主密钥进行加密,而是使用密码进行加密select * from sys.key_encryptions/*key_id	thumbprint	crypt_type	crypt_type_desc			crypt_property------	----------	----------	---------------------	------------------101		NULL		ESKP		ENCRYPTION BY PASSWORD	0xFB7D746C3CF0471147ECD710B1173B69A966421089FBB813BCF108E1ED90574F5C5F0998BA44F48869E05E9093BC59E6*/--删除测试数据drop certificate  Mycertificate;godrop master keygodrop table EnryptTestgo参考:服务主密钥:https://msdn.microsoft.com/zh-cn/library/ms189060(v=sql.90).aspx

插图2张:




  相关解决方案