SQL Server 连接加密 -- SQL Server connection encyption

转自:http://blogs.msdn.com/b/apgcdsd/archive/2011/03/22/sql-server-1-sql-server-connection-encyption.aspx


联机从书上提到过从SQL Server 2005开始,SQL Server和客户端的连接是自动加密的。但是你可能也注意到在SQL Server Configuration Manager里是有地方去设置加密与否的,而且这个选项默认是关闭的。这可能会显得有些自相矛盾了。此外你也可能注意到,Server Configuration Manager和加密相关的选项出现在了两个地方,一个是客户端选项,一个是服务器端选项,这些又都有些什么区别呢?今天我来详细解释下它们之间的关系。

 

SQL Server中的“加密”发生在什么地方


总的来说,我把SQL Server的加密分成两个部分,一个是对数据的加密,一个是对连接的加密。对于数据的加密,主要是通过一系列的函数如EncryptbyKey,或者TDE来完成的。这部分不在这里展开了。

另外一部分是连接加密,自己分的话还能分成两个阶段。一个是建立连接时候的加密。另外一个阶段是连接建立起来之后,客户端和SQL Server在其上传输数据时候的加密。

 

建立连接时的加密


联机丛书上所说的SQL Server会自动加密连接就是指的这个阶段。这个阶段开始于客户端和SQL Server在TCP/IP协议栈的三次握手,止于客户端成功登陆SQL Server。从SQL Server 2005开始,这个阶段永远是加密的。

那么SQL Server是使用什么密钥来对连接加密的呢?默认情况下SQL Server会自动生成一个证书并使用这个证书来对连接做SSL加密。

大家可能会在SQL Server的Error log的开头部分看到这么一段话:

 

A self-generated certificate was successfully loaded for encryption

  

这段话就表明了SQL Server在启动的时候自动加载了自动生成的证书并且使用这个证书来加密。

我们可以做一个实验来验证它。将SA的密码设置为Password,然后我们在远端机器上使用SQL Server Management Studio并使用SA账户去连接SQL Server。同时我们使用微软的Network Monitor工具来抓取SQL Server和客户端之间的网络包。使用SA账户来做这个实验是因为,SA账户是一个SQL 验证账户,而SQL验证账户的密码都是由客户端通过网络直接提交给SQL Sever来做验证的。这也是为什么说SQL验证不如Windows验证安全的原因。通过实验:

1.       我们可以看到有SSL的数据包交换,因此你判定SQL Server已经使用了SSL来加密了。

  

2.       检查所有网络包的内容,我们是找不到Password的,也就是说网络上传输的不再是明文而是加密过的内容。

  

需要注意的一点是,SQL  Server自动生成的证书是一种自签名的证书,而通过自签名证书实现的SSL并不能提供很强的安全性。他对中间人攻击(man-in-the-middle attack)不具有抵抗能力。因此我们建议在生产环境中,应该手动给SQL Server配置证书,而不是让它使用自动生成的证书。关于更多SQL Server配置证书的内容,可以参考这里。

我们继续讨论SQL Server在建立完连接后在该连接上的数据传送加密。

 

默认情况下SQL Server是否加密收发的数据包


答案是否定的。SQL Server默认只在建立连接时进行加密以保护客户端发送过来的账户登录信息

在上篇文章中所做的实验,我们可以看到SSL已经启用,并且在所有网络包中都找不到密码的明文。但是如果你选中任意一个TDS:SQLBatch的数据包,你可以看到类似如下的结果:

 

 

可以清楚的看到客户端发送的查询语句。如果你查看SQL Server返回来的数据包的话,你也同样能看到查询结果的数据明文。那么怎么来加密客户端和SQL Server之间传输的数据呢?

加密SQL Server收发的数据包


我们可以通过SQL Server的configuration Manager来配置SQL Server使得它加密和客户端之间的数据交换。在Configuration Manager中分别有两个地方来配置。

1.       SQL Server服务器端的加密配置。

 

如上图所示,右键点击“Protocols for MSSQLSERVER”,选择属性,你就可以看到Force Encryption选项。默认状态下这个选项是设置为No的,也就是说SQL Server不进行加密。

当把该选项设置为on之后,SQL Server就会要求对所有它和客户端之间的数据包传送进行加密,无论客户端是否配置为要求加密。此时用来加密的密钥仍旧是之前在建立连接阶段使用的证书。

需要注意的是,如果你是手动配置证书给SQL Server的话,你可能会发现一个现象。即使该证书已经过了有效期,或者该证书的根证书不受客户端的信任,客户端仍旧可以顺利的使用这个证书和SQL Server进行交流。这是一个by desing的行为。如果你要求你的客户端一定要信任该证书才可以连接的话,你就必须要配置客户端的加密选项。

如果你对如何手动配置证书不熟悉的话,可以参考这篇文章。

 

2.       客户端的加密配置。

如果SQL Server服务器端的Force Encryption的选项为No的话,那么是否对数据进行加密就完全取决于客户端的配置,也就是客户端的数据库连接驱动的配置。

在Configuration Manager中,可以配置Native Client驱动程序的加密配置,如下图所示。

 

 

当Force Protocol Encryption为Yes的话,就表明客户端要求加密数据包。此时客户一定要信任SQL Server端的证书,否则连接无法建立。另外,需要注意的是,此处的配置只对使用Native Client的客户端程序有效果。其他驱动程序也会有相应的方法分别作配置。如ODBC驱动就可以通过Cliconfg控制台来配置,等等。

如上面提到的,如果客户端要求加密的话,则客户端一定要信任服务器端的证书。在这种情况下,你手动配置的证书(无论你是从第三方获得的,还是企业内部证书服务器获得的,甚至是使用SelfSSL或者Makecert获得的证书)都是正常工作的。唯一的例外是SQL Server自动生成的证书。每次SQL Server启动时,它自动生成的证书都是不一样的,而且该证书的subject属性的CN域和SQL Server主机的FQDN是不一样的。这种情况下客户端是不信任这张证书的,因为它的CN域和FQDN不符合。



你可能感兴趣的:(DB,TDS)