在大家比较熟悉口令认证方法中,用户(被认证方)在访问主机之前,先向主机发出请求,接着主机发出一个质询(Challenge),然后被认证方返回一个响应(Response)。如果该响应通过了验证,用户就通过了身份认证,可以访问系统,否则他将被阻止访问系统。图3-1给出了一个简化的“质询-响应”认证示例。
图3-1 一个简化的“质询-响应”认证示例
在远程访问中,“质询-响应”认证可以避免在传输过程的泄露口令。
其他基于口令的认证系统,包括Kerberos,则要复杂得多,但是它们都依赖于一个简单的谬论:它们相信任何知道某个特定用户口令的人就是那个用户。基于口令的认证系统很多,以下是目前常用的类型:
(1)本地存储和比较。
(2)集中存储和比较。
(3)质询和响应。
(4)Kerberos。
(5)动态口令(或一次性口令,OTP)。
1. 本地存储和比较
早期的计算机系统不要求口令。任何人物理上拥有计算机系统就可以使用它。随着系统的发展,人们认识到需要限制对系统的访问,仅让少数拥有特权的人有权访问,用户身份识别系统就发展起来了。管理员把用户的口令录入到简单的机内数据中,并告诉用户。
最初,口令通常以明文的形式保存在数据库中,因为当时对口令的保护并不十分重要。所以,任何能够打开并读取该数据库文件的人就能知道其他人的口令。口令数据库的安全依赖于对该文件的访问控制,以及所有管理员和用户的善意。管理员负责更改口令、告知用户,以及为那些不记得口令的人恢复口令。后来,增加了用户可以更改自己的口令的功能,以及强制用户定期更改口令的功能。因为数据库中的所有信息都是明文的形式,所以认证算法比较简单:从控制台输入口令后,简单地与口令数据库中的口令进行比较,匹配则认证通过。
这个简单的认证过程,以前和现在都被广泛地用在那些需要内部认证过程的、现有的和定制的应用中。这些应用创建并管理它们自己的口令文件,并且不加密口令。口令的安全依赖于对口令文件的保护。因为口令会被流氓软件拦截到,所以这些系统不能很好地受到保护。
后来,Unix系统及某些其他操作系统使用密码技术来保护口令及口令文件,并且它们保存的是散列后的口令,而非口令自身。这个方案如图3-2所示。当系统新增一个用户时,用户要选择一个口令或者系统给用户分配一个口令,系统同时生成一个盐值(Salt)。在比较老的Unix系统中,盐值与口令被分配给用户时的时间有关。较新的系统中,盐值是一个伪随机数或真随机数。口令和盐值作为散列函数的输入,产生一个固定长度的散列值。然后,将该散列值、盐值和用户ID保存到口令文件中。这个过程如图3-2(a)所示。
当用户尝试登录操作系统时,用户要提供他的用户ID和口令。操作系统使用用户ID检索口令文件,找到对应的盐值和散列值(它与用户口令有关),然后采用相同的方法计算口令和盐值的散列值,并与口令文件中的散列值进行比较。如果二者相同,则说明用户提供的口令是正确的,用户通过身份验证。这个过程如图3-2(b)所示。
图3-2 Unix口令方案
上述口令方案中使用盐值的目的有3个:
(1)避免在口令文件中看到两个相同的口令。即使两个用户选择了相同的口令,也会因为盐值的不同,使得他们各自的“扩展”口令不同。
(2)极大增加了破解口令的难度。
(3)它使得发现一个用户是否在两个或多个系统上使用相同的口令变得不可能了。
随着时间的推移,口令文件的受限访问越来越受到重视。这促使很多系统努力隐藏口令文件或加强对它的防护。在早期的Unix系统中,口令被存储在/etc/passwd文件中。这个文件所有人都可以打开和读取。尽管其中的口令已加密,但是加密强度很弱,容易被破解。清空文件中的口令字段(如从光盘引导系统)后,用户根本不用口令就可以登录。经过几次高调的妥协后,该系统被重新设计成如今的样子。在大多数现代的Unix系统中,用户名保存在/etc/passwd文件中,而口令保存在/etc/shadow文件中,该文件被称为影子口令文件,它保存着加密的口令并且只有系统管理员可以访问它,因此普通用户要想攻破它更加困难了。
正如早期的Unix系统那样,早期的Windows版本使用比较容易被破解的口令文件(.pwd)。后来的Windows NT系统把口令保存到安全账户管理器(SAM)中,不过其中的口令能够被修改,或者用穷举攻击获得。后续的Windows版本增加了Syskey工具,它以额外的加密形式为SAM数据库增加了一层保护。尽管如此,某些攻击工具能够从Syskey保护的文件中导出口令的散列(或哈希)值。
很多免费的工具能够破解Windows和Unix的口令。最有名的两个是LC6(以前叫作LOphtCrack)和John the Ripper。这些工具常常通过组合攻击来破解口令:字典攻击(使用与操作系统相同的散列算法为某个“字典”中的“单词”生成散列值,然后将其与口令文件中的口令散列值进行比较,这里的“单词”,更多的是可能作为口令的各种字符串),启发式攻击(观察人们常做的事,如创建口令时开头用大写字母而结尾用数字),以及穷举攻击(检查每一个可能的字符组合)。
另一个攻击受口令保护的Windows系统的方法,是利用一个可以启动系统的Linux应用启动系统,然后使用该应用替换掉单机服务器上的管理员口令。如果攻击者能够接触计算机,他就能接管它。同样的方式也可以攻击其他操作系统。
早期的很多操作系统对账户数据库的保护非常弱。管理员通过对账户数据库使用比较强的授权控制来增强对它的保护。
无论如何,如果攻击者物理上占有了机器,或者攻击者能够得到存有口令的账户数据库文件,那么,利用众多的可用工具,他最终就能破解口令。这就是为什么每个系统都应该物理上受到保护,以及集中式账户数据库和认证系统应该使用额外的预防措施进行保护的原因。另外,对用户进行安全培训和对用户账户进行控制,也能够加强口令的安全,提高攻击者破解的难度—— 或许困难到让攻击者转而寻找其他容易的目标。
如今,许多现成的应用都使用很多公司在用的集中式认证系统,如轻量级目录访问协议(LDAP)或活动目录(AD)。它们依靠已有的用户凭证,而不是维护它们自己的口令数据库。这样做更安全,也更便于用户使用。单点登录(SSO)允许用户使用他们现有的凭证对应用进行身份验证,而不必经过前述的质询-响应过程,这样做改善了用户的体验。
2. 集中存储和比较
当口令被加密后,认证过程也改变了。此时不能仅仅通过直接比较来认证,系统必须先加密(使用与存储口令时相同的加密算法)用户输入的明文口令,然后将结果与口令文件中存储的加密口令进行比较。如果它们匹配,用户就通过了认证。这是如今很多操作系统和应用程序认证用户的方法。
当应用程序位于服务器上,客户端必须与它交互时,这又该如何变化呢?当集中式账户数据库位于远程主机上时,又将如何?有时候用户输入的口令加密后,通过网络传送到远程服务器,然后该服务器把它与本地存储的加密口令进行比较来完成身份认证。这是理想的情况。遗憾的是,一些网络应用以明文的形式传送口令,如Telnet、FTP、Rlogin,以及许多其他应用默认都是这样做的。即使本地系统是安全的,网络登录系统可能还是会使用那些明文传输口令的应用。如果攻击者能够在口令传输过程中捕获它们,就能使用它们登录系统。除了这些网络应用外,早期的远程认证协议(常常使用拨号登录),如口令认证协议(PAP),也以明文的形式把口令从客户端传送到服务器。
3. CHAP和MS-CHAP
一种解决保护网络传输中的认证凭证、使它们不易被捕获或重放的方法,是使用质询和响应认证协议CHAP(Challenge Handshake Authentication Protocol)或微软版本的MS-CHAP。这些协议使用到了散列函数MD5,并且服务器中存有各个客户端的口令。基本过程如下:服务器收到访问请求后,向请求者发出一个质询码。请求者使用MD5计算质询码和口令的散列值,然后将这个散列值发送给服务器。服务器收到后,将它与自己使用相同的方式计算的散列值进行比较。如果二者相同,则用户通过认证。
除了更加安全地存储凭证外,MS-CHAP的第2个版本还要求相互认证,也就是不仅客户端需要向服务器证明自己的身份,服务器也必须向客户端证明自己的身份。为此,服务器利用客户端的口令加密客户端发送过来的质询,然后返回给客户端。因为只有知道客户端口令(保存在服务器的账户数据库中)的服务器才能正确地加密客户端的质询,所以客户端也会确信它正在与一个有效的远程访问服务器通信。这个协议是一个更加强壮的协议,尽管并不是不可攻破的。已经发现MS-CHAP v2无法抵御穷举攻击,在现代计算机上,可以在数分钟内到数小时内攻破该协议。
4. Kerberos(www.daowen.com)
Kerberos是一个基于使用票据(Ticket)的网络认证系统。在Kerberos标准中,口令对于系统来说是关键,但是在某些系统中也可以用证书来替代口令。Kerberos是一个复杂的协议,由麻省理工学院开发,用于在一个不友好的网络中提供身份认证。不像某些其他网络认证系统的开发者,Kerberos的开发者假定恶意的用户和好奇的用户都能访问网络。因此,Kerberos设计了各种机制,用于处理对认证系统的常见攻击。Kerberos认证过程包括如下步骤(图3-3也给出了说明):
(1)用户输入他的口令。
(2)发送与客户端(或工作站)有关的数据和一个可能的鉴别码(Authenticator)到服务器;鉴别码是使用口令(可能散列过的或另外处理过的)加密一个时间戳(客户端计算机的时钟时间)生成的。鉴别码和明文时间戳一起构成一个登录请求,被客户端发送到Kerberos认证服务器(AS)。这就是KRB_AS_REQ消息。这被称为预认证,可能并不是所有的Kerberos实现都有这一步。
说明:通常情况下,AS和票据授予服务器(TGS)由同一个服务器担当,这个服务器扮演了密钥分发中心(KDC)的角色。该KDC是一个集中式的用户账户信息(包括口令)数据库。每个Kerberos域至少维护一个KDC(一个Kerberos域是一组服务器和客户机的一个逻辑集合,相当于一个Windows域)。
(3)KDC检查将来自客户端的时间戳与它自己的时间戳进行比较,二者相差不能超过规定的时间偏移(默认情况下是5 min),否则,请求将被拒绝。
(4)因为KDC保存有用户的口令,它可以使用该口令加密来自客户端的明文时间戳,并将结果与来自客户端的鉴别码进行比较。如果二者匹配,则用户通过身份认证,然后向客户端返回一个票据授予票据(TGT)。这就是KRB_AS_REP消息。
(5)当客户端需要访问特定的资源时,它将这个TGT和访问请求一起发送到KDC,发送的消息中也包含一个新的鉴别码。要访问的资源可能是客户端本地的资源或者是网络资源。这就是KRB_TGS_REQ消息。这个消息由TGS处理。
(6)KDC验证鉴别码并检查TGT。因为该TGT是KDC最初使用它自己的凭证加密TGT的一部分生成的,KDC能够验证该TGT是自己的。既然客户端还提供了一个有效的鉴别码,说明该TGT也不太可能是重放的结果(因为一个捕获的请求很可能有一个无效的时间戳,一个与KDC的时钟相比超过了规定的时间偏移的时间戳)。
(7)如果一切正常,KDC给客户端颁发一个服务票据(这就是消息KRB_TGS_REP), 客户端使用它就可以访问特定的资源了。该票据的部分内容用服务的凭据进行了加密(凭据可能是服务所在的计算机账户的口令),并且,该票据的另一部分内容用客户端的凭证进行了加密。
(8)客户端能够解密票据中使用它的凭证加密的那一部分,从而知道它可以使用哪些资源。客户端将这个票据连同一个新的鉴别码发送给资源所在的计算机。(最初登录期间,资源所在的计算机就是客户端计算机,服务票据在本地使用)
(9) 资源所在的计算机(客户端)通过检查时间是否在有效期内来验证时间戳,然后解密票据中使用它的凭证加密的那一部分。这会告诉它哪些资源被请求了,并证明了客户端已经通过身份验证。(只有KDC拥有资源所在的计算机的口令副本,并且KDC只有在客户端通过身份验证的情况下才会颁发一个票据。)资源所在的计算机(客户端)然后使用一个授权过程确定是否允许用户访问资源。
图3-3 Kerberos认证系统使用票据和一个多步骤过程
除了鉴别码和使用口令加密票据数据,也可以使用其他Kerberos控制。票据可以重复使用,但必须在有效期内。失效的票据可以续约,但是应该控制续约的次数。
然而,在大多数实现中,Kerberos依赖于口令,因此所有基于口令的认证系统的常规的注意事项都适用于Kerberos。如果能够得到用户的口令,认证系统无论有多强大都没用,因为该账户已经被攻破了。不过,到目前为止,还没有已知的成功攻击网上Kerberos数据的案例。对Kerberos成功攻击都是因为获得了口令数据库,或者通过界外攻击的方式(社会工程、意外发现口令等)获得了口令。
5. 一次性口令系统
有两个问题困扰着基于口令的认证系统。首先,在大多数情况下,口令是由人创建的。因此,人们需要知道如何构造强口令,但是大多数人并不知道如何构造强口令,或者即使知道也不重视。这些强口令必须被记住而不能写下来。这就意味着,在大多数情况下,不能要求使用长口令。其次,除了口令所有者外,其他人也可能会知道口令。人们经常把口令写下来,并常常放在可以被其他人找到的地方。有些人常常把自己的口令告诉给别人,根本不在乎可能会给自己带来的安全威胁。
口令会受到各种不同的攻击。它们能够被捕获和破解,或者用在重放攻击中,也就是口令被捕获,之后再次用于认证。
对于此类攻击的一种解决办法是,每次使用的口令都不相同。在计算机之外的系统中,利用一次性口令清单,这已经实现了。当两个人要发送加密信息的时候,如果他们各有一份一次性口令清单,每个人可以使用当天的口令(来加密信息),或者用其他方法决定使用哪个口令。此类系统的优势是,即使某个口令被破解了,它只影响当前的消息,对下一条消息没有影响,因为下一个消息使用不同的口令。那么,这可以在计算机系统中实现吗?当然可以,目前已有两种实现一次性口令(One-time Password)的方法:基于时间的一次性口令和基于序列的一次性口令。
基于时间的一次性口令系统使用基于硬件或软件的认证装置,该装置根据当前时间生成一个随机的种子。认证装置或者是硬件令牌(比如密钥坠、某种卡等),或者是软件形式。认证装置每60 s生成一个简单的一次性认证码。用户将该认证码和自己的个人识别码(PIN)组合在一起来创建口令。一个集中式的服务器能够验证这个口令,因为它的时钟是与令牌同步的,并且它知道用户的PIN。既然认证码每60 s改变一次,口令也会跟着改变。
这是一种双因子认证系统,因为它组合使用了你知道的东西,也就是你的PIN,以及你拥有的东西,也就是认证装置。
基于序列的一次性口令系统使用一个口令短语来生成一次性口令。口令短语和一个表示将会从中产生多少个口令的数字被输入到一个服务器中。每次发出认证请求的时候,该服务器都会生成一个新的口令。当用户在客户端输入口令短语的时候,作为一次性口令生成器的客户端软件将会生成相同的口令。因为服务器和客户端都知道口令短语,并且它们都设置了相同的、口令短语能够被使用的次数,所以服务器和客户端能够独立地产生相同的口令。
这个算法包含了口令短语的一系列散列值和一个质询。首次使用的时候,散列的次数等于口令短语可能被使用的次数。每使用一次,散列的次数就减少一次。最终,口令短语可被使用的次数会用完,这个时候,要么需要设置一个新的口令短语,要么重置旧的口令短语。
当客户端系统发出一个认证请求的时候,服务器发出一个质询(Challenge)。该质询包含一个散列算法标识(MD5或者SHA-1)、一个序列号和一个种子(一个1~16个字符的明文字符串)。就像这样:opt-md5 569 mycaristoyota。一次性口令生成器把来自服务器的质询和用户输入的口令短语作为输入,生成一个长度为64 bit的一次性口令。该口令必须被输入到系统中。在某些情况下这是自动完成的,在另外一些情况下可以通过剪切和粘贴完成,有些情况则需要用户手动输入。这个口令被用于加密质询以创建响应(Response)。然后,客户端将这个响应发送给服务器,服务器验证它是否有效。这个过程包括如下步骤(图3-4也给出了说明):
(1)用户输入口令短语。
(2)客户端向服务器发出认证请求。
(3)服务器向客户端发送一个质询。
(4)客户端和服务器上的一次性口令生成器各自生成一个一次性口令。它们是相同的。
(5)客户端的一次性口令或者直接由系统完成输入,或者显示出来,再由用户输入。这个口令用于加密质询(创建响应)。
(6)客户端将响应发送给服务器。
(7)服务器用它自己生成的一次性口令加密质询,并将结果与来自客户端的响应进行比较。
(8)如果二者相同,则用户通过认证。
图3-4 基于序列的一次性口令是一个改进的质询/响应认证系统
基于序列的一次性口令系统,像其他一次性口令系统一样,提供了对窃听和重放攻击的防御,但是却没有对传输数据的隐私提供保护,也没有对会话劫持攻击进行防御。不过,这可以通过某些安全的通道,如IPSec或SSH,来提供额外的保护。一次性口令系统的其他缺点在于其可能的实现。因为最终必须重置口令短语,其实现应该以一种安全的方式完成口令短语的重置。如果不这样的话,攻击者可能会捕获到口令短语,从而为进一步攻击口令系统做好准备。在某些系统中,基于序列的一次性口令的实现保留了传统的登录方式。当用户面对选择使用传统的登录方式,还是输入一个复杂的口令短语然后再输入一个长长的一次性口令时,他可能会选择使用传统的登录方式,这样做使认证过程变弱了。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。