证书和非对称密钥使用数据库级的内部公钥加密数据,并且使用数据库级内部私钥解密数据。而对称密钥相对简单,它们包含一个同时用来加密和解密的密钥。困此,使用对称密钥加密数据更快,并且用在大数据时更加合适。尽管复杂度是考虑使用它的因素,但它仍然是一个很好的加密数据的选择。
我们看一组例子:
示例一、创建对称密钥
对称密钥的特性是:在数据库会话中使用它对数据进行加密和解密前必须首先打开。
创建对称密钥使用如下命令:CREATE SYMMETRIC KEY 创建对称密钥。(http://msdn.microsoft.com/en-us/library/ms188357.aspx)
1 |
<ol class="dp-sql"><li class="alt"><span><span>use DB_Encrypt_Demo </span></span></li><li><span>go </span></li><li class="alt"><span class="comment"><font color="#008200">-- 创建一个用于加密对称密钥的非对称密钥 </font></span><span> </span></li><li><span class="keyword"><strong><font color="#006699">CREATE</font></strong></span><span> ASYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> symDemoKey </span><span class="comment"><font color="#008200">--名称 </font></span><span> </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">WITH</font></strong></span><span> ALGORITHM = RSA_512 </span><span class="comment"><font color="#008200">--加密算法 </font></span><span> </span></li><li><span>ENCRYPTION </span><span class="keyword"><strong><font color="#006699">BY</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">PASSWORD</font></strong></span><span> = </span><span class="string"><font color="#0000ff">'TestSYM456!'</font></span><span class="comment"><font color="#008200">--密码 </font></span><span> </span></li><li class="alt"><span class="comment"><font color="#008200">-- 创建一个对称密钥 </font></span><span> </span></li><li><span class="keyword"><strong><font color="#006699">CREATE</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> sym_Demo </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">WITH</font></strong></span><span> ALGORITHM = TRIPLE_DES </span></li><li><span>ENCRYPTION </span><span class="keyword"><strong><font color="#006699">BY</font></strong></span><span> ASYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> symDemoKey </span></li><li class="alt"><span> </span></li></ol> |
示例二、查看当前数据库中的对称密钥
使用目录视图sys.symmetric_keys(http://msdn.microsoft.com/en-us/library/ms189446.aspx)来查看。
1 |
<ol class="dp-sql"><li class="alt"><span><span class="comment"><font color="#008200">--查看当前数据库中的非对称密钥 </font></span><span> </span></span></li><li><span>use DB_Encrypt_Demo </span></li><li class="alt"><span>go </span></li><li><span class="keyword"><strong><font color="#006699">SELECT</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">name</font></strong></span><span>, algorithm_desc </span><span class="keyword"><strong><font color="#006699">FROM</font></strong></span><span> sys.symmetric_keys </span></li><li class="alt"><span class="comment"><font color="#008200">----结果返回 </font></span><span> </span></li><li><span>/* </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">name</font></strong></span><span> algorithm_desc </span></li><li><span>sym_Demo TRIPLE_DES </span></li><li class="alt"><span>*/ </span></li><li><span> </span></li></ol> |
示例三、修改非对称密钥的加密方式
你可以使用ALTER SYMMETRIC KEY(http://technet.microsoft.com/en-us/library/ms189440.aspx)命令修改对称密钥的加密方式。但执行前必须使用OPEN SYMMETRIC KEY(http://msdn.microsoft.com/en-us/library/ms190499.aspx)命令打开它。
1 |
<ol class="dp-sql"><li class="alt"><span><span>use DB_Encrypt_Demo </span></span></li><li><span>go </span></li><li class="alt"><span class="comment"><font color="#008200">--先用私钥密码打开对称密钥 </font></span><span> </span></li><li><span class="keyword"><strong><font color="#006699">OPEN</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> sym_Demo </span></li><li class="alt"><span>DECRYPTION </span><span class="keyword"><strong><font color="#006699">BY</font></strong></span><span> ASYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> symDemoKey </span></li><li><span class="keyword"><strong><font color="#006699">WITH</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">PASSWORD</font></strong></span><span> = </span><span class="string"><font color="#0000ff">'TestSYM456!'</font></span><span> </span></li><li class="alt"><span class="comment"><font color="#008200">--打开之后,先增加密码加密,取代原密钥 </font></span><span> </span></li><li><span class="keyword"><strong><font color="#006699">ALTER</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> sym_Demo </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">ADD</font></strong></span><span> ENCRYPTION </span><span class="keyword"><strong><font color="#006699">BY</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">PASSWORD</font></strong></span><span> = </span><span class="string"><font color="#0000ff">'newnew!456'</font></span><span> </span></li><li><span class="comment"><font color="#008200">--再删除非对称密钥加密 </font></span><span> </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">ALTER</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> sym_Demo </span></li><li><span class="keyword"><strong><font color="#006699">DROP</font></strong></span><span> ENCRYPTION </span><span class="keyword"><strong><font color="#006699">BY</font></strong></span><span> ASYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> symDemoKey </span></li><li class="alt"><span class="comment"><font color="#008200">--完成操作后,关闭对称密钥 </font></span><span> </span></li><li><span class="keyword"><strong><font color="#006699">CLOSE</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> sym_Demo </span></li></ol> |
示例四、使用对称密钥对数据进行加密和解密。
1、为了使用对称密钥对数据进行加密,必须首先打开它,然后使用函数EncryptByKey 加密数据。(http://msdn.microsoft.com/zh-cn/library/ms174361.aspx)
2、使用DecryptByKey来解密使用对称密钥加密的数据。注意DecryptByKey不像甩EncryptByKey,无须使用对称密钥GUID。因此,为了解密,必须打开正确的对称密钥会话,否则会显示null。
下面是一个例子:
1 |
<ol class="dp-sql"><li class="alt"><span><span>/***************************************************/ </span></span></li><li><span>USE DB_Encrypt_Demo </span></li><li class="alt"><span>GO </span></li><li><span class="comment"><font color="#008200">--创建测试数据表,用于对称加密 </font></span><span> </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">CREATE</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">TABLE</font></strong></span><span> dbo.PWDQuestion </span></li><li><span>(CustomerID </span><span class="keyword"><strong><font color="#006699">int</font></strong></span><span> </span><span class="op"><font color="#808080">NOT</font></span><span> </span><span class="op"><font color="#808080">NULL</font></span><span> </span><span class="keyword"><strong><font color="#006699">PRIMARY</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span>, </span></li><li class="alt"><span>PasswordHintQuestion nvarchar(300) </span><span class="op"><font color="#808080">NOT</font></span><span> </span><span class="op"><font color="#808080">NULL</font></span><span>, </span></li><li><span>PasswordHintAnswer varbinary(200) </span><span class="op"><font color="#808080">NOT</font></span><span> </span><span class="op"><font color="#808080">NULL</font></span><span>) </span></li><li class="alt"><span>GO </span></li><li><span class="comment"><font color="#008200">--插入加密数据 </font></span><span> </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">OPEN</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> sym_Demo </span></li><li><span>DECRYPTION </span><span class="keyword"><strong><font color="#006699">BY</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">PASSWORD</font></strong></span><span> = </span><span class="string"><font color="#0000ff">'newnew!456'</font></span><span> </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">INSERT</font></strong></span><span> dbo.PWDQuestion </span></li><li><span>(CustomerID, PasswordHintQuestion, PasswordHintAnswer) </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">VALUES</font></strong></span><span> </span></li><li><span>(12, </span><span class="string"><font color="#0000ff">'您出生的医院名称?'</font></span><span>, </span></li><li class="alt"><span>EncryptByKey(Key_GUID(</span><span class="string"><font color="#0000ff">'sym_Demo '</font></span><span>), </span><span class="string"><font color="#0000ff">'杭州市一'</font></span><span>)) </span></li><li><span class="keyword"><strong><font color="#006699">CLOSE</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> sym_Demo </span></li><li class="alt"><span> </span></li></ol> |
查看未加密的数据:
--解密数据
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword"><strong><font color="#006699">OPEN</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> sym_Demo </span></span></li><li><span>DECRYPTION </span><span class="keyword"><strong><font color="#006699">BY</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">PASSWORD</font></strong></span><span> = </span><span class="string"><font color="#0000ff">'newnew!456'</font></span><span> </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">SELECT</font></strong></span><span> CustomerID,PasswordHintQuestion, </span></li><li><span class="func"><font color="#ff1493">CAST</font></span><span>(DecryptByKey(PasswordHintAnswer) </span><span class="keyword"><strong><font color="#006699">as</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">varchar</font></strong></span><span>(200)) PasswordHintAnswer </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">FROM</font></strong></span><span> dbo.PWDQuestion </span></li><li><span class="keyword"><strong><font color="#006699">WHERE</font></strong></span><span> CustomerID = 12 </span></li><li class="alt"><span class="comment"><font color="#008200">--打开后切记关闭!!! </font></span><span> </span></li><li><span class="keyword"><strong><font color="#006699">CLOSE</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> sym_Demo </span></li></ol> |
1 |
<ol class="dp-sql"><li class="alt"><span><span class="comment"><font color="#008200">--不打开直接读取 </font></span><span> </span></span></li><li><span class="keyword"><strong><font color="#006699">SELECT</font></strong></span><span> CustomerID,PasswordHintQuestion, </span></li><li class="alt"><span class="func"><font color="#ff1493">CAST</font></span><span>(DecryptByKey(PasswordHintAnswer) </span><span class="keyword"><strong><font color="#006699">as</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">varchar</font></strong></span><span>(200)) PasswordHintAnswer </span></li><li><span class="keyword"><strong><font color="#006699">FROM</font></strong></span><span> dbo.PWDQuestion </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">WHERE</font></strong></span><span> CustomerID = 12 </span></li><li><span> </span></li></ol> |
至此,好像已经大功告成了,别,千万别高兴得太早!
这里有个问题,如果恶意用户不知道CustomerID=13的PasswordHintAnswer列的真实值,但知道CustomerID=14的PasswordHintAnswer列的真实值,则完全可以通过恶意替换PasswordHintAnswer列而绕过加密!!此时,我们索性连CustomerID列作为验证列也一起加密,以绝后患 !
注意:加密的验证列也可以由另一个相关表的列作为参数传入。
看一个完整的例子:
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword"><strong><font color="#006699">truncate</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">table</font></strong></span><span> dbo.PWDQuestion </span></span></li><li><span>go </span></li><li class="alt"><span class="comment"><font color="#008200">--添加两个未加密的行 </font></span><span> </span></li><li><span class="keyword"><strong><font color="#006699">INSERT</font></strong></span><span> dbo.PWDQuestion </span></li><li class="alt"><span>(CustomerID, PasswordHintQuestion, PasswordHintAnswer) </span></li><li><span class="keyword"><strong><font color="#006699">select</font></strong></span><span> 13, </span><span class="string"><font color="#0000ff">'您出生的医院名称?'</font></span><span>,</span><span class="func"><font color="#ff1493">cast</font></span><span>(</span><span class="string"><font color="#0000ff">'浙江妇保院'</font></span><span> </span><span class="keyword"><strong><font color="#006699">as</font></strong></span><span> varbinary) </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">union</font></strong></span><span> </span><span class="op"><font color="#808080">all</font></span><span> </span></li><li><span class="keyword"><strong><font color="#006699">select</font></strong></span><span> 14, </span><span class="string"><font color="#0000ff">'您出生的医院名称?'</font></span><span>,</span><span class="func"><font color="#ff1493">cast</font></span><span>(</span><span class="string"><font color="#0000ff">'浙江妇保二院'</font></span><span> </span><span class="keyword"><strong><font color="#006699">as</font></strong></span><span> varbinary) </span></li><li class="alt"><span class="comment"><font color="#008200">--打开对称密钥,连CustomerID列一起加密 </font></span><span> </span></li><li><span class="keyword"><strong><font color="#006699">OPEN</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> sym_Demo </span></li><li class="alt"><span>DECRYPTION </span><span class="keyword"><strong><font color="#006699">BY</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">PASSWORD</font></strong></span><span> = </span><span class="string"><font color="#0000ff">'newnew!456'</font></span><span> </span></li><li><span class="keyword"><strong><font color="#006699">UPDATE</font></strong></span><span> dbo.PWDQuestion </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">SET</font></strong></span><span> PasswordHintAnswer = </span></li><li><span>EncryptByKey(Key_GUID(</span><span class="string"><font color="#0000ff">'sym_Demo'</font></span><span>), </span></li><li class="alt"><span>PasswordHintAnswer,1,</span><span class="comment"><font color="#008200">--1表示使用验证器值 </font></span><span> </span></li><li><span class="func"><font color="#ff1493">CAST</font></span><span>(CustomerID </span><span class="keyword"><strong><font color="#006699">as</font></strong></span><span> varbinary)) </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">WHERE</font></strong></span><span> CustomerID </span><span class="op"><font color="#808080">in</font></span><span> (13,14) </span></li><li><span class="comment"><font color="#008200">--打开后切记关闭!!! </font></span><span> </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">CLOSE</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> sym_Demo </span></li><li><span class="comment"><font color="#008200">--此时必须这样查看原数据 </font></span><span> </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">OPEN</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> sym_Demo </span></li><li><span>DECRYPTION </span><span class="keyword"><strong><font color="#006699">BY</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">PASSWORD</font></strong></span><span> = </span><span class="string"><font color="#0000ff">'newnew!456'</font></span><span> </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">SELECT</font></strong></span><span> CustomerID,PasswordHintQuestion, </span></li><li><span class="func"><font color="#ff1493">CAST</font></span><span>(DecryptByKey(PasswordHintAnswer, 1,</span><span class="comment"><font color="#008200">--1表示使用验证器值 </font></span><span> </span></li><li class="alt"><span class="func"><font color="#ff1493">CAST</font></span><span>(CustomerID </span><span class="keyword"><strong><font color="#006699">as</font></strong></span><span> varbinary)) </span><span class="keyword"><strong><font color="#006699">as</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">varchar</font></strong></span><span>(200)) PasswordHintAnswer </span></li><li><span class="keyword"><strong><font color="#006699">FROM</font></strong></span><span> dbo.PWDQuestion </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">WHERE</font></strong></span><span> CustomerID = 13 </span></li><li><span class="comment"><font color="#008200">--打开后切记关闭!!! </font></span><span> </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">CLOSE</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> sym_Demo </span></li><li><span> </span></li></ol> |
恶意替换开始:
1 |
<ol class="dp-sql"><li class="alt"><span><span>/********************************************************** </span></span></li><li><span class="comment"><font color="#008200">--我们用刚才的CustomerID = 13的PasswordHintAnswer列值 </font></span><span> </span></li><li class="alt"><span class="comment"><font color="#008200">--替换CustomerID = 14的PasswordHintAnswer列值, </font></span><span> </span></li><li><span class="comment"><font color="#008200">--再用刚才读取14的方法读取真实值**********************************************************/ </font></span><span> </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">update</font></strong></span><span> dbo.PWDQuestion </span><span class="keyword"><strong><font color="#006699">set</font></strong></span><span> PasswordHintAnswer= </span></li><li><span>(</span><span class="keyword"><strong><font color="#006699">select</font></strong></span><span> PasswordHintAnswer </span><span class="keyword"><strong><font color="#006699">from</font></strong></span><span> dbo.PWDQuestion </span><span class="keyword"><strong><font color="#006699">where</font></strong></span><span> CustomerID = 14) </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">where</font></strong></span><span> CustomerID = 13 </span></li></ol> |
此时,我们再查看:
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword"><strong><font color="#006699">OPEN</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> sym_Demo </span></span></li><li><span>DECRYPTION </span><span class="keyword"><strong><font color="#006699">BY</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">PASSWORD</font></strong></span><span> = </span><span class="string"><font color="#0000ff">'newnew!456'</font></span><span> </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">SELECT</font></strong></span><span> CustomerID,PasswordHintQuestion, </span></li><li><span class="func"><font color="#ff1493">CAST</font></span><span>(DecryptByKey(PasswordHintAnswer, 1,</span><span class="comment"><font color="#008200">--1表示使用验证器值 </font></span><span> </span></li><li class="alt"><span class="func"><font color="#ff1493">CAST</font></span><span>(CustomerID </span><span class="keyword"><strong><font color="#006699">as</font></strong></span><span> varbinary)) </span><span class="keyword"><strong><font color="#006699">as</font></strong></span><span> </span><span class="keyword"><strong><font color="#006699">varchar</font></strong></span><span>(200)) </span></li><li><span>PasswordHintAnswer,PasswordHintAnswer </span><span class="keyword"><strong><font color="#006699">as</font></strong></span><span> binaryValue </span></li><li class="alt"><span class="keyword"><strong><font color="#006699">FROM</font></strong></span><span> dbo.PWDQuestion </span></li><li><span class="keyword"><strong><font color="#006699">WHERE</font></strong></span><span> CustomerID </span><span class="op"><font color="#808080">in</font></span><span>(13,14) </span></li><li class="alt"><span class="comment"><font color="#008200">--打开后切记关闭!!! </font></span><span> </span></li><li><span class="keyword"><strong><font color="#006699">CLOSE</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> sym_Demo </span></li></ol> |
郎勒个郎!爽吧!虽然复制了相同的二进制数据,可是读取结果令攻击者大失所望啊!
示例五、删除对称密钥
命令:DROP SYMMETRIC KEY 删除指定的对称密钥( http://technet.microsoft.com/en-us/library/ms182698.aspx)
例子:
1 |
<ol class="dp-sql"><li class="alt"><span><span class="keyword"><strong><font color="#006699">DROP</font></strong></span><span> SYMMETRIC </span><span class="keyword"><strong><font color="#006699">KEY</font></strong></span><span> symDemoKey </span></span></li></ol> |
注意:如果加密密钥打开没有关闭,则drop失败。
小结:
1、本文主要介绍对称密钥的创建、删除、查看以及用它来修改加密方式、进行数据的加密和解密。
2、对称密钥的特性是:在数据库会话中使用它对数据进行加密和解密前必须首先打开。
3、对称密钥可用于大数据的加密。
下文将主要介绍证书加密(Certificate Encryption)
原文链接:http://www.cnblogs.com/downmoon/archive/2011/03/15/1984352.html