目前人们对于
SQLSERVER处理登录密码的方式存在一些误解
。希望阅读本文后
,你能够对这些概念有清楚的认识
。需要注意的是
,只有
SQL验证才会涉及到登录密码,WINDOWS验证模式不需要密码。
第一个错误概念是SQLSERVER会对登录密码进行加密,然后储存起来。这是错误的。SQLSERVER存储的是经过HASH后的密码。HASH和加密的不同之处在于其难于反向破解--但是对于加密算法而言,只要掌握密钥就可以轻易获得明文。从HASH后的字符中找出原始明文是非常困难的(除非你已经知道了明文)。不选择加密而选择HASH的优点是无需保护密钥(参见之前的文章)。那么SQLSERVER是如何处理登录密码的呢?登录时,首先对用户提交的密码进行HASH处理,然后和SQLSERVER存储的HASH后的密码进行比较。如果匹配,则登录成功。当然,你也可以使用一个错误的密码成功登陆SQLSERVER,只要HASH后的文本和原始密码的HASH值一致即可。但找出这样一个不同的密码是非常困难的(比中乐透要难多了)。同时也要记住,这种算法的强度也依赖于密码自身是否难猜。
那么怎样去破解登录密码呢?主要的方法就是建立一个集合(通常叫做字典),该集合内包含可能和登录密码匹配的文本,然后依次尝试集合中的所有文本,直到成功匹配。字典可以包含日期,各种语言的名词,数字或特殊字符等等。因此,保护密码的主要方法就是尽量选择一个不会出现在字典内的文本作为密码。如果你想选择一个好的密码,可以搜索关键字"how to choose a password",你会找到许多很好的建议。即使你认为你已经选择了一个好的密码,你也应该浏览这些内容-----你也许会发现你的密码并没有想象中的那么“强壮”
边注:一些文档将HASH称之为“难以逆转的加密”,我不同意这种观点。我觉得“不可逆转的加密”本身就很矛盾,因为加密中的“逆转”是指找到合适的解密密钥。
第二个错误的概念是:SQLSERVER所用的HASH算法是MS内部开发的。我要阐述一下关于SQLSERVER算法的历史,但是之前我要声明:这是错误的。SQLSERVER从2000开始使用SHA1算法,6.5本版和7.0版本使用的算法为Snefru。关于6.5版本之前的情况我并不清楚,因为我是在SQLSERVER6.5加入的。
接下来是对6.5及以后本版的的概述。在6.5版本中,密码只能是ASCII字符,因此Snefru算法也只应用于ASCII字符。在7.0版本中,Unicode字符也可以作为密码,因此Snefru算法也应用到了Unicode字符。这是6.5和7.0中的主要不同。在2000版本中,使用的HASH算法改为SHA1,但也向后兼容。SQLSERVER会保存经过HASH后的密码,同时也会保留一份将密码转换成大写形式的HASH后的文本,这样就允许大小写不敏感的密码。David Litchfield 的写过一篇长,批评了这个问题。 有一点非常重要:大小写不敏感的HASH更容易被破解,因为这减小了字典的大小。 基于此原因,SQLSERVER2005没有采用大小写不敏感的的做法,这样更有利于
安全。SQLSERVER2005中的另一个改变是删除了一些系统视图,HASH后的密码只对sysadmin可见。
在应用中,很少会使用到HASH后的密码。HASH变化后的密码主要应用于CREATE LOGIN DDL和SP2后ALTER LOGIN DDL中。 除非万不得已,最好不要使用HASH后的密码。只有在下面的场景中应使用HASH密码:应用程序需要在各个
服务器间使用相同的密码。 CREATE LOGIN DLL可以应用于SQLSERVER7.0,2000和2005中,并在2005中支持HASH选项;而ALTER LOGIN DDL只在2000及2005中使用。请注意,SQLSERVER2005不再支持SQLSERVER6.5里的HASH。SQLSERVER2000中对大小写不敏感的特性也在2005中移除。如果将SQLSERVER从7.0升级到2005,其秘密存储的格式会在以下任意情况发生时转换到SQLSERVER2005的格式:登录成功或者成功改变密码(当指定了OLD_PASSword)
原文地址:SQL Server 2005: About login password hashes
虽然SHA1早已经被破解了,但是理解SQLSERVER密码的存储方式仍然非常重要。因此我翻译此文,希望对您有所帮助